Layout21 icon indicating copy to clipboard operation
Layout21 copied to clipboard

TOML `SerializationFormat` fails for `GdsLibrary`

Open dan-fritchman opened this issue 2 years ago • 3 comments

This:

/// Create an empty library with known dates
fn empty_lib() -> GdsLibrary {
    // Create an empty library
    let mut lib = GdsLibrary::new("empty");
    // Set its dates to some known value, so we can check it round-trips
    lib.dates = test_dates();
    // And return it for other test
    lib 
}
#[test]
fn empty_lib_to_toml() -> GdsResult<()> {
    let lib = empty_lib();
    Toml.save(&lib, &resource("empty.gds.toml")).expect("save failed");
    Ok(())
}

Fails with:

failures:

---- tests::empty_lib_to_toml stdout ----
thread 'tests::empty_lib_to_toml' panicked at 'save failed: Error(UnsupportedType)', gds21/src/tests.rs:214:50
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Notes:

  • Yaml & Json both work
  • Yaml, Json, and Toml all work for lef21::LefLibrary

Unclear at this point what the UnsupportedType is.

Unclear when this was injected, as we had generally only been testing one format of serialization (GDS to JSON, LEF to YAML, nothing to TOML). And it wasn't clear that there are value-types supported in YAML & JSON that aren't in TOML(?). Apparently GdsLibrary has one or more of them.

dan-fritchman avatar Dec 15 '22 20:12 dan-fritchman

Rooting around GdsLibrary, without testing this at all, I have a bet, and that bet is, it's this date & time stuff:

/// # Gds Date & Time
///
/// In typical cases, a wrapper around a [`NaiveDateTime`] with custom serialization.
/// For existing GDSII files with invalid dates, the raw twelve bytes are stored instead.
///
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
pub enum GdsDateTime {
    /// Valid Date & Time
    DateTime(NaiveDateTime),
    /// Raw Bytes as stored in GDSII
    Bytes([i16; 6]),
}

dan-fritchman avatar Dec 19 '22 00:12 dan-fritchman

Bet lost.
Datetimes are not a part of GdsLibrary as of acd6ac7, and this still fails.

Errors have upgraded to:

---- gds_serialization::tests::golden_toml stdout ----
GdsStats { libraries: 1, structs: 1, boundaries: 144, paths: 0, struct_refs: 0, array_refs: 0, text_elems: 10, nodes: 0, boxes: 0 }
thread 'gds_serialization::tests::golden_toml' panicked at 'Could not save output file: values must be emitted before tables', layout21converters/src/gds_serialization.rs:56:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

We've got an open question with the toml authors as to what should work here. I think our stuff should? But clearly it doesn't.

dan-fritchman avatar Dec 19 '22 18:12 dan-fritchman

https://github.com/toml-rs/toml/issues/396 was recently closed, and updated in TOML v0.6. Commit 812ee2d includes v0.6. It makes the empty GDS to TOML work. But the sample in layout21converters/ continues to fail, now (and after peeling off our own errors) with:

     Running `gds2toml -i resources/sky130_fd_sc_hd__dfxtp_1.gds -o test.toml`
thread 'main' panicked at 'Could not save output file: unsupported GdsElement type', layout21converters/src/gds_serialization.rs:42:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

This is hitting TOML's unsupported_type function and error-variant.

Much of the guesswork (by me) thus far on the TOML issue is that this boils down to TOML's "values must come before tables" rule. It seems (from its commentary) that the Rust TOML package should paper over this. But then again maybe not.

dan-fritchman avatar Jan 25 '23 21:01 dan-fritchman