Skip to content

Incorrect handling of optional fields with String #7

@ghostinushanka

Description

@ghostinushanka

Hello @benhall-7 ,

Playing with the lib I've come across inconsistent behavior for structs containing String types.
Example:

use diff::Diff;

#[derive(Debug, PartialEq, Diff)]
#[diff(attr(
    #[derive(Debug, PartialEq)]
))]
struct OptionalInteger {
    x: i32,
    ox: Option<i32>,
}

#[derive(Debug, PartialEq, Diff)]
#[diff(attr(
    #[derive(Debug, PartialEq)]
))]
struct OptionalString {
    x: String,
    ox: Option<String>,
}

fn main() {
    let empty_integer = OptionalInteger { x: 42, ox: None };
    let filled_integer = OptionalInteger { x: 42, ox: Some(42)};
    let di = empty_integer.diff(&filled_integer);
    println!("{:#?}", di);

    let empty_string = OptionalString { x: "42".to_string(), ox: None};
    let filled_string = OptionalString { x: "42".to_string(), ox: Some("42".to_string())};
    let ds = empty_string.diff(&filled_string);
    println!("{:#?}", ds);
}

Expected output:

OptionalIntegerDiff {
    x: 0,
    ox: Some(
        42,
    ),
}
OptionalStringDiff {
    x: None,
    ox: Some(
        "42",
    ),
}

Actual output (note how instead of Some(String) we're getting Some(Some(String))

OptionalIntegerDiff {
    x: 0,
    ox: Some(
        42,
    ),
}
OptionalStringDiff {
    x: None,
    ox: Some(
        Some(
            "42",
        ),
    ),
}

Make it Option<Vec<String>> (or other compound type for that matter) and the end result is even more interesting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions