davnotdev / quick-type-schema

BSD 2-Clause "Simplified" License
1 stars 0 forks source link

Enum variant causing quicktype code generation failure #1

Closed JonasESmith closed 5 months ago

JonasESmith commented 5 months ago

[!NOTE] this could be an expected outcome for this, however I needed to run down what was causing this.

Code to reproduce

/// session without the macros... 
pub struct Session {
    //  ... other
    pub items: Vec<SessionItem>,
}

pub enum SessionItem {
    Workout(Workout),
    // ... other
}

pub struct Workout {
    /// ... other 
    pub workout_type: WorkoutType,
}

pub enum WorkoutType {
    Basic(), // this is causing the issue, and `Basic,` doesn't work. 
    TimeSpan { duration_seconds: u64 },
    Strength { reps: u32, sets: u32, weight: f64 },
}

let mut codegen = CodegenContext::new(Some(&["-l", "dart", "--use-freezed"]));

codegen.add_type::<Session>(); // the issue is found nested in the session struct. 

let session_object = codegen.finish(Language::Dart);

println!("{}", session_object);

Error message

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.45s
Running `target/debug/rcg_api`
["-o", "/var/folders/mg/8hl52rnx7fb7nbsmrc06bpxm0000gn/T/quick-type-code-dart-50011", "--src-lang", "schema", "/var/folders/mg/8hl52rnx7fb7nbsmrc06bpxm0000gn/T/quick-type-schema-50011.json", "-l", "dart", "--use-freezed"] /var/folders/mg/8hl52rnx7fb7nbsmrc06bpxm0000gn/T/quick-type-code-dart-50011 /var/folders/mg/8hl52rnx7fb7nbsmrc06bpxm0000gn/T/quick-type-schema-50011.json
thread 'main' panicked at /Users/{...}/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quick-type-schema-0.1.0/src/lib.rs:103:57:
called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }

When navigating to /Users/{...}/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quick-type-schema-0.1.0/src/lib.rs:103:57

This is the line it points to

let output = std::fs::read_to_string(&out_path).unwrap();

Solution

before change

pub enum WorkoutType {
    Basic(),
    TimeSpan { duration_seconds: u64 },
    Strength { reps: u32, sets: u32, weight: f64 },
}

originally was the bellow, however wasn't outputting the correct enum in dart.

pub enum WorkoutType {
    Basic,
    TimeSpan { duration_seconds: u64 },
    Strength { reps: u32, sets: u32, weight: f64 },
}

After change

pub enum WorkoutType {
    Basic(i32), // or `Basic {},` worked as well. 
    TimeSpan { duration_seconds: u64 },
    Strength { reps: u32, sets: u32, weight: f64 },
}
davnotdev commented 5 months ago

Thank you for submitting this very detailed report. Unfortunately, there are no workarounds I can apply for this case. serde encodes Basic as { "example": "Basic" } and Basic() as { "example": { "Basic": [] } }. quicktype fails to parse this specific case of an empty array in a union type despite this being valid JSON schema. This issue most likely stems from this comment within quicktype.

Moving forward, I have added error handling for quicktype errors and for when the expected output file is not found (similar to this case). I also added an option for --use-freezed for dart, so you can now use Language::Dart { use_freezed: true }. These changes should accessible in v0.1.1 via cargo update. Thanks again for submitting this issue, and have a nice day :)