diff --git a/Cargo.lock b/Cargo.lock index ab6f6e0649..3a643ffd39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -351,9 +351,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "capnp" -version = "0.20.6" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053b81915c2ce1629b8fb964f578b18cb39b23ef9d5b24120d0dfc959569a1d9" +checksum = "d55799fdec2a55eee8c267430d7464eb9c27ad2e5c8a49b433ff213b56852c7f" dependencies = [ "embedded-io", ] diff --git a/Cargo.toml b/Cargo.toml index 5f956b65bd..2a19ff63c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ debug_assert_with_mut_call = "warn" anyhow = "1.0.98" insta = { version = "1.43.1" } bitvec = "1.0.1" -capnp = "0.20.6" +capnp = "0.21.3" cgmath = "0.18.0" cool_asserts = "2.0.3" delegate = "0.13.4" diff --git a/hugr-model/capnp/hugr-v0.capnp b/hugr-model/capnp/hugr-v0.capnp index 18a13f71b1..7891b7f245 100644 --- a/hugr-model/capnp/hugr-v0.capnp +++ b/hugr-model/capnp/hugr-v0.capnp @@ -20,6 +20,12 @@ using LinkIndex = UInt32; struct Package { modules @0 :List(Module); + version @1 :Version; +} + +struct Version { + major @0 :UInt32; + minor @1 :UInt32; } struct Module { diff --git a/hugr-model/src/capnp/hugr_v0_capnp.rs b/hugr-model/src/capnp/hugr_v0_capnp.rs index ec4e137acc..9e0a6ed7b3 100644 --- a/hugr-model/src/capnp/hugr_v0_capnp.rs +++ b/hugr-model/src/capnp/hugr_v0_capnp.rs @@ -72,11 +72,19 @@ pub mod package { pub fn has_modules(&self) -> bool { !self.reader.get_pointer_field(0).is_null() } + #[inline] + pub fn get_version(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn has_version(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } } pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } impl <> ::capnp::traits::HasStructSize for Builder<'_,> { - const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 0, pointers: 1 }; + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 0, pointers: 2 }; } impl <> ::capnp::traits::HasTypeId for Builder<'_,> { const TYPE_ID: u64 = _private::TYPE_ID; @@ -142,6 +150,22 @@ pub mod package { pub fn has_modules(&self) -> bool { !self.builder.is_pointer_field_null(0) } + #[inline] + pub fn get_version(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn set_version(&mut self, value: crate::hugr_v0_capnp::version::Reader<'_>) -> ::capnp::Result<()> { + ::capnp::traits::SetterInput::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) + } + #[inline] + pub fn init_version(self, ) -> crate::hugr_v0_capnp::version::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(1), 0) + } + #[inline] + pub fn has_version(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } } pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } @@ -151,19 +175,23 @@ pub mod package { } } impl Pipeline { + pub fn get_version(&self) -> crate::hugr_v0_capnp::version::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(1)) + } } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 37] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 53] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(56, 36, 26, 168, 243, 12, 207, 208), ::capnp::word(20, 0, 0, 0, 1, 0, 0, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), - ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(93, 1, 0, 0, 166, 1, 0, 0), ::capnp::word(21, 0, 0, 0, 226, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(29, 0, 0, 0, 63, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 119, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(99, 97, 112, 110, 112, 47, 104, 117), @@ -171,14 +199,21 @@ pub mod package { ::capnp::word(112, 110, 112, 58, 80, 97, 99, 107), ::capnp::word(97, 103, 101, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), - ::capnp::word(4, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(13, 0, 0, 0, 66, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 66, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(8, 0, 0, 0, 3, 0, 1, 0), - ::capnp::word(36, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(64, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(61, 0, 0, 0, 66, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(56, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(68, 0, 0, 0, 2, 0, 1, 0), ::capnp::word(109, 111, 100, 117, 108, 101, 115, 0), ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -191,15 +226,24 @@ pub mod package { ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(118, 101, 114, 115, 105, 111, 110, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(167, 171, 245, 145, 177, 155, 108, 182), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ]; pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { match index { 0 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), - _ => panic!("invalid field index {}", index), + 1 => ::introspect(), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -207,13 +251,237 @@ pub mod package { members_by_discriminant: MEMBERS_BY_DISCRIMINANT, members_by_name: MEMBERS_BY_NAME, }; - pub static NONUNION_MEMBERS : &[u16] = &[0]; + pub static NONUNION_MEMBERS : &[u16] = &[0,1]; pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; - pub static MEMBERS_BY_NAME : &[u16] = &[0]; + pub static MEMBERS_BY_NAME : &[u16] = &[0,1]; pub const TYPE_ID: u64 = 0xd0cf_0cf3_a81a_2438; } } +pub mod version { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <> ::core::marker::Copy for Reader<'_,> {} + impl <> ::core::clone::Clone for Reader<'_,> { + fn clone(&self) -> Self { *self } + } + + impl <> ::capnp::traits::HasTypeId for Reader<'_,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <> ::core::fmt::Debug for Reader<'_,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <> Reader<'_,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_major(self) -> u32 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_minor(self) -> u32 { + self.reader.get_data_field::(1) + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <> ::capnp::traits::HasStructSize for Builder<'_,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 1, pointers: 0 }; + } + impl <> ::capnp::traits::HasTypeId for Builder<'_,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <> ::capnp::traits::SetterInput> for Reader<'_,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_major(self) -> u32 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_major(&mut self, value: u32) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_minor(self) -> u32 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_minor(&mut self, value: u32) { + self.builder.set_data_field::(1, value); + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 49] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), + ::capnp::word(167, 171, 245, 145, 177, 155, 108, 182), + ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), + ::capnp::word(0, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(168, 1, 0, 0, 230, 1, 0, 0), + ::capnp::word(21, 0, 0, 0, 226, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(99, 97, 112, 110, 112, 47, 104, 117), + ::capnp::word(103, 114, 45, 118, 48, 46, 99, 97), + ::capnp::word(112, 110, 112, 58, 86, 101, 114, 115), + ::capnp::word(105, 111, 110, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(48, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(45, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(109, 97, 106, 111, 114, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 105, 110, 111, 114, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => ::introspect(), + _ => ::capnp::introspect::panic_invalid_field_index(index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + members_by_name: MEMBERS_BY_NAME, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0,1]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub static MEMBERS_BY_NAME : &[u16] = &[0,1]; + pub const TYPE_ID: u64 = 0xb66c_9bb1_91f5_aba7; + } +} + pub mod module { #[derive(Copy, Clone)] pub struct Owned(()); @@ -424,13 +692,14 @@ pub mod module { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 90] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 91] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(167, 107, 35, 13, 152, 216, 48, 189), ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(3, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(232, 1, 0, 0, 98, 2, 0, 0), ::capnp::word(21, 0, 0, 0, 218, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -522,11 +791,11 @@ pub mod module { 1 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), 2 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), 3 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -802,13 +1071,14 @@ pub mod node { } } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 126] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 127] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(108, 130, 159, 249, 96, 124, 57, 228), ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(5, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(100, 2, 0, 0, 46, 3, 0, 0), ::capnp::word(21, 0, 0, 0, 202, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -938,11 +1208,11 @@ pub mod node { 3 => <::capnp::primitive_list::Owned as ::capnp::introspect::Introspect>::introspect(), 4 => <::capnp::primitive_list::Owned as ::capnp::introspect::Introspect>::introspect(), 5 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -1393,13 +1663,14 @@ pub mod operation { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 229] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 230] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(216, 191, 119, 93, 53, 241, 240, 155), ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(1, 0, 7, 0, 0, 0, 14, 0), ::capnp::word(2, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(48, 3, 0, 0, 38, 5, 0, 0), ::capnp::word(21, 0, 0, 0, 242, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -1640,11 +1911,11 @@ pub mod operation { 11 => <::capnp::text::Owned as ::capnp::introspect::Introspect>::introspect(), 12 => ::introspect(), 13 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -1841,13 +2112,14 @@ pub mod operation { } } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 48] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 49] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(156, 202, 42, 93, 60, 14, 161, 193), ::capnp::word(30, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(216, 191, 119, 93, 53, 241, 240, 155), ::capnp::word(1, 0, 7, 0, 1, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(21, 0, 0, 0, 66, 1, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -1895,11 +2167,11 @@ pub mod operation { match index { 0 => ::introspect(), 1 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -2137,13 +2409,14 @@ pub mod symbol { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 104] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 105] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(63, 209, 84, 70, 225, 154, 206, 223), ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(3, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 5, 0, 0, 195, 5, 0, 0), ::capnp::word(21, 0, 0, 0, 218, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -2250,11 +2523,11 @@ pub mod symbol { 2 => <::capnp::primitive_list::Owned as ::capnp::introspect::Introspect>::introspect(), 3 => ::introspect(), 4 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -2542,13 +2815,14 @@ pub mod region { } } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 141] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 142] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(225, 113, 253, 231, 231, 39, 130, 153), ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(5, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(197, 5, 0, 0, 168, 6, 0, 0), ::capnp::word(21, 0, 0, 0, 218, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -2694,11 +2968,11 @@ pub mod region { 4 => <::capnp::primitive_list::Owned as ::capnp::introspect::Introspect>::introspect(), 5 => ::introspect(), 6 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -2863,13 +3137,14 @@ pub mod region_scope { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 48] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 49] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(163, 135, 81, 30, 243, 205, 148, 170), ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(0, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(170, 6, 0, 0, 236, 6, 0, 0), ::capnp::word(21, 0, 0, 0, 2, 1, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -2917,11 +3192,11 @@ pub mod region_scope { match index { 0 => ::introspect(), 1 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -2969,13 +3244,14 @@ impl ::capnp::traits::HasTypeId for RegionKind { const TYPE_ID: u64 = 0xe457_1af6_23a3_76b4u64; } mod region_kind { -pub static ENCODED_NODE: [::capnp::Word; 32] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), +pub static ENCODED_NODE: [::capnp::Word; 33] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(180, 118, 163, 35, 246, 26, 87, 228), ::capnp::word(20, 0, 0, 0, 2, 0, 0, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(238, 6, 0, 0, 53, 7, 0, 0), ::capnp::word(21, 0, 0, 0, 250, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -3004,7 +3280,7 @@ pub static ENCODED_NODE: [::capnp::Word; 32] = [ ::capnp::word(109, 111, 100, 117, 108, 101, 0, 0), ]; pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } } @@ -3361,13 +3637,14 @@ pub mod term { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 167] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 168] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(178, 107, 91, 137, 60, 121, 191, 207), ::capnp::word(20, 0, 0, 0, 1, 0, 2, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(1, 0, 7, 0, 0, 0, 10, 0), ::capnp::word(2, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(55, 7, 0, 0, 105, 9, 0, 0), ::capnp::word(21, 0, 0, 0, 202, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 23, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -3542,11 +3819,11 @@ pub mod term { 7 => ::introspect(), 8 => <() as ::capnp::introspect::Introspect>::introspect(), 9 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -3744,13 +4021,14 @@ pub mod term { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 49] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 50] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(136, 151, 188, 135, 237, 57, 73, 141), ::capnp::word(25, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(178, 107, 91, 137, 60, 121, 191, 207), ::capnp::word(0, 0, 7, 0, 0, 0, 2, 0), ::capnp::word(2, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(251, 8, 0, 0, 103, 9, 0, 0), ::capnp::word(21, 0, 0, 0, 10, 1, 0, 0), ::capnp::word(37, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -3799,11 +4077,11 @@ pub mod term { match index { 0 => ::introspect(), 1 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -3986,13 +4264,14 @@ pub mod term { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 51] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 52] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(150, 98, 109, 181, 159, 123, 122, 222), ::capnp::word(25, 0, 0, 0, 1, 0, 2, 0), ::capnp::word(178, 107, 91, 137, 60, 121, 191, 207), ::capnp::word(1, 0, 7, 0, 1, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(21, 0, 0, 0, 250, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -4043,11 +4322,11 @@ pub mod term { match index { 0 => ::introspect(), 1 => <::capnp::primitive_list::Owned as ::capnp::introspect::Introspect>::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -4212,13 +4491,14 @@ pub mod term { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 48] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 49] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(55, 205, 218, 56, 109, 17, 119, 134), ::capnp::word(25, 0, 0, 0, 1, 0, 2, 0), ::capnp::word(178, 107, 91, 137, 60, 121, 191, 207), ::capnp::word(1, 0, 7, 0, 1, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(21, 0, 0, 0, 18, 1, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -4266,11 +4546,11 @@ pub mod term { match index { 0 => ::introspect(), 1 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -4448,13 +4728,14 @@ pub mod param { impl Pipeline { } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 48] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + pub static ENCODED_NODE: [::capnp::Word; 49] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(232, 73, 199, 85, 129, 167, 53, 211), ::capnp::word(20, 0, 0, 0, 1, 0, 1, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(107, 9, 0, 0, 163, 9, 0, 0), ::capnp::word(21, 0, 0, 0, 210, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -4502,11 +4783,11 @@ pub mod param { match index { 0 => <::capnp::text::Owned as ::capnp::introspect::Introspect>::introspect(), 1 => ::introspect(), - _ => panic!("invalid field index {}", index), + _ => ::capnp::introspect::panic_invalid_field_index(index), } } pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { encoded_node: &ENCODED_NODE, @@ -4554,13 +4835,14 @@ impl ::capnp::traits::HasTypeId for Visibility { const TYPE_ID: u64 = 0x8d83_15f2_7a68_8301u64; } mod visibility { -pub static ENCODED_NODE: [::capnp::Word; 31] = [ - ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), +pub static ENCODED_NODE: [::capnp::Word; 32] = [ + ::capnp::word(0, 0, 0, 0, 6, 0, 6, 0), ::capnp::word(1, 131, 104, 122, 242, 21, 131, 141), ::capnp::word(20, 0, 0, 0, 2, 0, 0, 0), ::capnp::word(1, 150, 80, 40, 197, 50, 43, 224), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(165, 9, 0, 0, 235, 9, 0, 0), ::capnp::word(21, 0, 0, 0, 250, 0, 0, 0), ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -4588,6 +4870,6 @@ pub static ENCODED_NODE: [::capnp::Word; 31] = [ ::capnp::word(112, 117, 98, 108, 105, 99, 0, 0), ]; pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { - panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + ::capnp::introspect::panic_invalid_annotation_indices(child_index, index) } } diff --git a/hugr-model/src/lib.rs b/hugr-model/src/lib.rs index c139cefc42..f99ecfe0d3 100644 --- a/hugr-model/src/lib.rs +++ b/hugr-model/src/lib.rs @@ -5,6 +5,8 @@ mod capnp; pub mod v0; +mod version; +pub use version::*; // This is required here since the generated code assumes it's in the package root. use capnp::hugr_v0_capnp; diff --git a/hugr-model/src/v0/binary/read.rs b/hugr-model/src/v0/binary/read.rs index 05ada8dcfe..a2b6ef38e9 100644 --- a/hugr-model/src/v0/binary/read.rs +++ b/hugr-model/src/v0/binary/read.rs @@ -1,6 +1,6 @@ use crate::capnp::hugr_v0_capnp as hugr_capnp; -use crate::v0 as model; use crate::v0::table; +use crate::{Version, v0 as model}; use bumpalo::Bump; use bumpalo::collections::Vec as BumpVec; use std::io::BufRead; @@ -13,6 +13,15 @@ pub enum ReadError { #[from(forward)] /// An error encountered while decoding a model from a `capnproto` buffer. DecodingError(capnp::Error), + + /// The file could not be read due to a version mismatch. + #[display("Can not read file with version {actual} (tooling version {current}).")] + VersionError { + /// The current version of the hugr-model format. + current: Version, + /// The version of the hugr-model format in the file. + actual: Version, + }, } type ReadResult = Result; @@ -58,6 +67,16 @@ fn read_package<'a>( bump: &'a Bump, reader: hugr_capnp::package::Reader, ) -> ReadResult> { + let version = read_version(reader.get_version()?)?; + let current_version = Version::current(); + + if version.major != current_version.major || version.minor > current_version.minor { + return Err(ReadError::VersionError { + current: current_version, + actual: version, + }); + } + let modules = reader .get_modules()? .iter() @@ -67,6 +86,12 @@ fn read_package<'a>( Ok(table::Package { modules }) } +fn read_version(reader: hugr_capnp::version::Reader) -> ReadResult { + let major = reader.get_major(); + let minor = reader.get_minor(); + Ok(Version { minor, major }) +} + fn read_module<'a>( bump: &'a Bump, reader: hugr_capnp::module::Reader, diff --git a/hugr-model/src/v0/binary/write.rs b/hugr-model/src/v0/binary/write.rs index 0ac28b15ef..1fcf3d0c15 100644 --- a/hugr-model/src/v0/binary/write.rs +++ b/hugr-model/src/v0/binary/write.rs @@ -1,8 +1,8 @@ use std::io::Write; +use crate::Version; use crate::capnp::hugr_v0_capnp as hugr_capnp; -use crate::v0 as model; -use crate::v0::table; +use crate::v0::{self as model, table}; /// An error encounter while serializing a model. #[derive(Debug, derive_more::From, derive_more::Display, derive_more::Error)] @@ -47,6 +47,12 @@ pub fn write_to_vec(package: &table::Package) -> Vec { fn write_package(mut builder: hugr_capnp::package::Builder, package: &table::Package) { write_list!(builder, init_modules, write_module, package.modules); + write_version(builder.init_version(), Version::current()); +} + +fn write_version(mut builder: hugr_capnp::version::Builder, version: Version) { + builder.set_major(version.major); + builder.set_minor(version.minor); } fn write_module(mut builder: hugr_capnp::module::Builder, module: &table::Module) { diff --git a/hugr-model/src/version.rs b/hugr-model/src/version.rs new file mode 100644 index 0000000000..2cbb2f8d3e --- /dev/null +++ b/hugr-model/src/version.rs @@ -0,0 +1,74 @@ +use derive_more::derive::Display; +use std::{str::FromStr, sync::LazyLock}; +use thiserror::Error; + +/// A version number. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Display)] +#[display("{major}.{minor}")] +pub struct Version { + /// The major part of the version. + pub major: u32, + /// The minor part of the version. + pub minor: u32, +} + +impl Version { + /// The current version of the HUGR model format. + pub fn current() -> Self { + static VERSION: LazyLock = LazyLock::new(|| { + include_str!("../version.txt") + .trim() + .parse() + .expect("`version.txt` in `hugr-model` contains version that fails to parse") + }); + + *VERSION + } +} + +impl FromStr for Version { + type Err = VersionParseError; + + fn from_str(s: &str) -> Result { + let (major, minor) = s.split_once(".").ok_or(VersionParseError)?; + let major = major.parse().map_err(|_| VersionParseError)?; + let minor = minor.parse().map_err(|_| VersionParseError)?; + Ok(Self { major, minor }) + } +} + +/// Error when parsing a [`Version`]. +#[derive(Debug, Clone, Error)] +#[error("failed to parse version")] +pub struct VersionParseError; + +#[cfg(test)] +mod test { + use super::Version; + use std::{hint::black_box, str::FromStr}; + + #[test] + fn test_parse() { + assert_eq!( + Version::from_str("0.1").unwrap(), + Version { major: 0, minor: 1 } + ); + assert_eq!( + Version::from_str("1337.0").unwrap(), + Version { + major: 1337, + minor: 0 + } + ); + assert!(Version::from_str("0").is_err()); + assert!(Version::from_str("0.").is_err()); + assert!(Version::from_str("0.1.").is_err()); + assert!(Version::from_str("0...").is_err()); + assert!(Version::from_str("").is_err()); + } + + #[test] + fn test_current() { + black_box(Version::current()); + } +} diff --git a/hugr-model/version.txt b/hugr-model/version.txt new file mode 100644 index 0000000000..ba66466c2a --- /dev/null +++ b/hugr-model/version.txt @@ -0,0 +1 @@ +0.0