diff --git a/rust/derive/tests/base.rs b/rust/derive/tests/base.rs index 1d1db83..2fcf0b4 100644 --- a/rust/derive/tests/base.rs +++ b/rust/derive/tests/base.rs @@ -29,7 +29,7 @@ mod common; use std::convert::Infallible; use strict_encoding::{ - StrictDecode, StrictDumb, StrictEncode, StrictSerialize, StrictSum, VariantError, + StrictDecode, StrictDumb, StrictEncode, StrictSerde, StrictSerialize, StrictSum, VariantError, }; const TEST_LIB: &str = "TestLib"; @@ -192,7 +192,8 @@ fn enum_custom_tags() -> common::Result { Five {}, } - impl StrictSerialize for Assoc {} + impl StrictSerde<255> for Assoc {} + impl StrictSerialize<255> for Assoc {} assert_eq!(Assoc::ALL_VARIANTS, &[ (0, "one"), @@ -203,13 +204,13 @@ fn enum_custom_tags() -> common::Result { ]); let assoc = Assoc::Two(0, 1, 2); - assert_eq!(assoc.to_strict_serialized::<256>().unwrap().as_slice(), &[2, 0, 1, 0, 2, 0, 0, 0]); + assert_eq!(assoc.to_strict_serialized().unwrap().as_slice(), &[2, 0, 1, 0, 2, 0, 0, 0]); let assoc = Assoc::One { hash: [0u8; 32], ord: 0, }; - assert_eq!(assoc.to_strict_serialized::<256>().unwrap().as_slice(), &[0u8; 34]); + assert_eq!(assoc.to_strict_serialized().unwrap().as_slice(), &[0u8; 34]); Ok(()) } diff --git a/rust/derive/tests/type.rs b/rust/derive/tests/type.rs index d904b5c..dc6ae87 100644 --- a/rust/derive/tests/type.rs +++ b/rust/derive/tests/type.rs @@ -30,7 +30,7 @@ extern crate strict_encoding_derive; mod common; use strict_encoding::{ - tn, StrictDeserialize, StrictSerialize, StrictStruct, StrictSum, StrictType, + tn, StrictDeserialize, StrictSerde, StrictSerialize, StrictStruct, StrictSum, StrictType, }; const TEST_LIB: &str = "TestLib"; @@ -126,8 +126,9 @@ fn skip_field() -> common::Result { #[strict_type(skip)] wrong_name: u8, } - impl StrictSerialize for Struct {} - impl StrictDeserialize for Struct {} + impl StrictSerde<{ u16::MAX as usize }> for Struct {} + impl StrictSerialize<{ u16::MAX as usize }> for Struct {} + impl StrictDeserialize<{ u16::MAX as usize }> for Struct {} assert_eq!(Struct::ALL_FIELDS, &["mustCamelize"]); @@ -135,7 +136,7 @@ fn skip_field() -> common::Result { must_camelize: 2, wrong_name: 3, }; - assert_eq!(val.to_strict_serialized::<{ usize::MAX }>().unwrap().as_slice(), &[2]); + assert_eq!(val.to_strict_serialized().unwrap().as_slice(), &[2]); let val = Struct { must_camelize: 2, wrong_name: 0, diff --git a/rust/src/file.rs b/rust/src/file.rs new file mode 100644 index 0000000..91f9fa2 --- /dev/null +++ b/rust/src/file.rs @@ -0,0 +1,35 @@ +// Strict encoding library for deterministic binary serialization. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Written in 2019-2024 by +// Dr. Maxim Orlovsky +// +// Copyright 2022-2024 UBIDECO Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use amplify::Bytes32; + +/// File header for strict-serialized content. +/// +/// The header has a fixed size of 128 bytes. +pub struct StrictFileHeader { + // Constant "SE" + pub magic: [u8; 4], + pub max_len: u64, + pub lib_name: [u8; 26], + pub type_name: [u8; 26], + pub sem_id: Bytes32, + pub checksum: Bytes32, +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 40f9f65..0845d07 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -60,6 +60,7 @@ mod embedded; pub mod stl; #[cfg(test)] pub(crate) mod test; +mod file; pub use embedded::{Byte, DecodeRawLe}; pub use error::{DecodeError, DeserializeError, SerializeError}; diff --git a/rust/src/traits.rs b/rust/src/traits.rs index 7347572..6202227 100644 --- a/rust/src/traits.rs +++ b/rust/src/traits.rs @@ -379,21 +379,23 @@ impl StrictDecode for PhantomData { fn strict_decode(_reader: &mut impl TypedRead) -> Result { Ok(default!()) } } -pub trait StrictSerialize: StrictEncode { - fn strict_serialized_len(&self) -> io::Result { +/// Ensures that both [`StrictSerialize`] and [`StrictDeserialize`], when both implemented, has the +/// same maximum length requirements. +pub trait StrictSerde: StrictType {} + +pub trait StrictSerialize: StrictSerde + StrictEncode { + fn strict_serialized_len(&self) -> io::Result { let counter = StrictWriter::counter::(); Ok(self.strict_encode(counter)?.unbox().unconfine().count) } - fn to_strict_serialized( - &self, - ) -> Result, 0, MAX>, SerializeError> { + fn to_strict_serialized(&self) -> Result, 0, MAX>, SerializeError> { let ast_data = StrictWriter::in_memory::(); let data = self.strict_encode(ast_data)?.unbox().unconfine(); Confined::, 0, MAX>::try_from(data).map_err(SerializeError::from) } - fn strict_serialize_to_file( + fn strict_serialize_to_file( &self, path: impl AsRef, ) -> Result<(), SerializeError> { @@ -405,8 +407,8 @@ pub trait StrictSerialize: StrictEncode { } } -pub trait StrictDeserialize: StrictDecode { - fn from_strict_serialized( +pub trait StrictDeserialize: StrictSerde + StrictDecode { + fn from_strict_serialized( ast_data: Confined, 0, MAX>, ) -> Result { let mut reader = StrictReader::in_memory::(ast_data); @@ -418,7 +420,7 @@ pub trait StrictDeserialize: StrictDecode { Ok(me) } - fn strict_deserialize_from_file( + fn strict_deserialize_from_file( path: impl AsRef, ) -> Result { let file = fs::File::open(path)?;