diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e6a1846..63ba6ea 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,7 +60,7 @@ jobs: strategy: fail-fast: false matrix: - toolchain: [ nightly, beta, stable, 1.77.0 ] + toolchain: [ nightly, beta, stable, 1.81.0 ] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master diff --git a/Cargo.lock b/Cargo.lock index 5d7abca..e8533a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,7 +9,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "448cf0c3afc71439b5f837aac5399a1ef2b223f5f38324dbfb4343deec3b80cc" dependencies = [ "amplify_apfloat", - "amplify_derive", "amplify_num", "amplify_syn", "ascii", @@ -29,18 +28,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "amplify_derive" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a6309e6b8d89b36b9f959b7a8fa093583b94922a0f6438a24fb08936de4d428" -dependencies = [ - "amplify_syn", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "amplify_num" version = "0.5.3" @@ -286,7 +273,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "strict_encoding" -version = "2.8.1" +version = "3.0.0-alpha.1" dependencies = [ "amplify", "getrandom", @@ -300,7 +287,7 @@ dependencies = [ [[package]] name = "strict_encoding_derive" -version = "2.8.1" +version = "3.0.0-alpha.1" dependencies = [ "amplify", "amplify_syn", @@ -314,7 +301,7 @@ dependencies = [ [[package]] name = "strict_encoding_test" -version = "2.8.1" +version = "3.0.0-alpha.1" dependencies = [ "amplify", "strict_encoding", diff --git a/Cargo.toml b/Cargo.toml index 54fc315..f746442 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,14 +4,14 @@ default-members = ["rust", "rust/derive", "rust/test_helpers"] resolver = "2" [workspace.package] -version = "2.8.1" +version = "3.0.0-alpha.1" authors = ["Dr Maxim Orlovsky "] homepage = "https://strict-types.org" repository = "https://github.com/strict-types/strict-encoding" -rust-version = "1.77.0" +rust-version = "1.81.0" edition = "2021" license = "Apache-2.0" [workspace.dependencies] -amplify = { version = "4.8.0" } +amplify = { version = "4.8.0", default-features = false } serde_crate = { package = "serde", version = "1", features = ["derive"] } diff --git a/MANIFEST.yml b/MANIFEST.yml deleted file mode 100644 index 8b4c7bc..0000000 --- a/MANIFEST.yml +++ /dev/null @@ -1,13 +0,0 @@ -Name: strict_encoding -Type: Library -Kind: Free software -License: Apache-2.0 -Language: Rust -Compiler: 1.77 -Author: Maxim Orlovsky -Maintained: UBIDECO Labs, Institute for Distributed and Cognitive Computing, Switzerland -Maintainers: - Maxim Orlovsky: - GitHub: @dr-orlovsky - GPG: EAE730CEC0C663763F028A5860094BAF18A26EC9 - EMail: orlovsky@ubideco.org diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 8b105e9..18b0022 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -14,8 +14,8 @@ readme = "README.md" exclude = ["derive", "test_helpers"] [dependencies] -amplify = { workspace = true, features = ["proc_attr"] } -strict_encoding_derive = { version = "2.8.0", path = "derive" } +amplify = { workspace = true, features = ["proc_attr", "hex"] } +strict_encoding_derive = { version = "3.0.0-alpha.1", path = "derive" } serde_crate = { workspace = true, optional = true } [dev-dependencies] @@ -32,13 +32,15 @@ wasm-bindgen-test = "0.3" [features] default = [ - "derive" + "derive", ] all = [ + "std", "float", "derive", "serde" ] +std = ["amplify/std", "serde_crate/std"] derive = [] float = [ "amplify/apfloat", diff --git a/rust/derive/src/derive_encode.rs b/rust/derive/src/derive_encode.rs index 0b03f0a..fbe4896 100644 --- a/rust/derive/src/derive_encode.rs +++ b/rust/derive/src/derive_encode.rs @@ -56,7 +56,7 @@ impl DeriveInner for DeriveEncode<'_> { } Ok(quote! { - fn strict_encode(&self, writer: W) -> ::std::io::Result { + fn strict_encode(&self, writer: W) -> Result { use #crate_name::{TypedWrite, WriteStruct, fname}; writer.write_struct::(|w| { Ok(w @@ -80,7 +80,7 @@ impl DeriveInner for DeriveEncode<'_> { }); Ok(quote! { - fn strict_encode(&self, writer: W) -> ::std::io::Result { + fn strict_encode(&self, writer: W) -> Result { use #crate_name::{TypedWrite, WriteTuple}; writer.write_tuple::(|w| { Ok(w @@ -203,7 +203,7 @@ impl DeriveInner for DeriveEncode<'_> { }; Ok(quote! { - fn strict_encode(&self, writer: W) -> ::std::io::Result { + fn strict_encode(&self, writer: W) -> Result { use #crate_name::TypedWrite; #inner } diff --git a/rust/src/embedded.rs b/rust/src/embedded.rs index b05c68b..15f62e5 100644 --- a/rust/src/embedded.rs +++ b/rust/src/embedded.rs @@ -19,10 +19,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::{BTreeMap, BTreeSet, VecDeque}; -use std::hash::Hash; -use std::io; -use std::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8}; +use alloc::collections::{BTreeMap, BTreeSet, VecDeque}; +use core::hash::Hash; +use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8}; use amplify::ascii::AsciiString; use amplify::confinement::Confined; @@ -35,8 +34,8 @@ use crate::stl::AsciiSym; use crate::{ DecodeError, DefineUnion, Primitive, RString, ReadRaw, ReadTuple, ReadUnion, RestrictedCharSet, Sizing, StrictDecode, StrictDumb, StrictEncode, StrictProduct, StrictStruct, StrictSum, - StrictTuple, StrictType, StrictUnion, TypeName, TypedRead, TypedWrite, WriteRaw, WriteTuple, - WriteUnion, LIB_EMBEDDED, + StrictTuple, StrictType, StrictUnion, TypeName, TypedRead, TypedWrite, WriteError, WriteRaw, + WriteTuple, WriteUnion, LIB_EMBEDDED, }; pub trait DecodeRawLe: Sized { @@ -53,7 +52,7 @@ pub trait DecodeRawLe: Sized { pub struct Byte(u8); impl StrictEncode for Byte { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { unsafe { writer = writer.register_primitive(Primitive::BYTE); writer.raw_writer().write_raw::<1>([self.0])?; @@ -69,7 +68,7 @@ macro_rules! encode_num { fn strict_name() -> Option { Some(tn!(stringify!($id))) } } impl $crate::StrictEncode for $ty { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { unsafe { writer = writer.register_primitive(Primitive::$id); writer.raw_writer().write_raw_array(self.to_le_bytes())?; @@ -78,13 +77,15 @@ macro_rules! encode_num { } } impl $crate::DecodeRawLe for $ty { - fn decode_raw_le(reader: &mut (impl ReadRaw + ?Sized)) -> Result { + fn decode_raw_le( + reader: &mut (impl ReadRaw + ?Sized), + ) -> Result { let buf = reader.read_raw_array::<{ Self::BITS as usize / 8 }>()?; Ok(Self::from_le_bytes(buf)) } } impl $crate::StrictDecode for $ty { - fn strict_decode(reader: &mut impl TypedRead) -> Result { + fn strict_decode(reader: &mut impl TypedRead) -> Result { Self::decode_raw_le(unsafe { reader.raw_reader() }) } } @@ -98,7 +99,7 @@ macro_rules! encode_nonzero { fn strict_name() -> Option { Some(tn!(stringify!($id))) } } impl $crate::StrictEncode for $ty { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { unsafe { writer = writer.register_primitive(Primitive::$id); writer.raw_writer().write_raw_array(self.get().to_le_bytes())?; @@ -107,7 +108,7 @@ macro_rules! encode_nonzero { } } impl $crate::StrictDecode for $ty { - fn strict_decode(reader: &mut impl TypedRead) -> Result { + fn strict_decode(reader: &mut impl TypedRead) -> Result { let buf = unsafe { reader.raw_reader().read_raw_array::<{ Self::BITS as usize / 8 }>()? }; let v = <$p>::from_le_bytes(buf); @@ -126,7 +127,7 @@ macro_rules! encode_float { } #[cfg(feature = "float")] impl $crate::StrictEncode for $ty { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { let mut be = [0u8; $len]; be.copy_from_slice(&self.to_bits().to_le_bytes()[..$len]); unsafe { @@ -138,7 +139,7 @@ macro_rules! encode_float { } #[cfg(feature = "float")] impl $crate::StrictDecode for $ty { - fn strict_decode(reader: &mut impl TypedRead) -> Result { + fn strict_decode(reader: &mut impl TypedRead) -> Result { const BYTES: usize = <$ty>::BITS / 8; let mut inner = [0u8; 32]; let buf = unsafe { reader.raw_reader().read_raw_array::()? }; @@ -211,7 +212,7 @@ where T: Default + StrictStruct impl StrictEncode for Box where T: StrictEncode { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { self.as_ref().strict_encode(writer) } } @@ -242,7 +243,7 @@ where T: StrictType } impl StrictUnion for Option where T: StrictType {} impl StrictEncode for Option { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { writer.write_union::(|u| { let u = u.define_unit(vname!("none")).define_newtype::(vname!("some")).complete(); @@ -269,7 +270,7 @@ impl StrictType for () { fn strict_name() -> Option { None } } impl StrictEncode for () { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { Ok(unsafe { writer.register_primitive(Primitive::UNIT) }) } } @@ -286,7 +287,7 @@ impl StrictTuple for (A, B) { const FIELD_COUNT: u8 = 2; } impl StrictEncode for (A, B) { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { writer.write_tuple::(|w| Ok(w.write_field(&self.0)?.write_field(&self.1)?.complete())) } } @@ -316,7 +317,7 @@ impl impl StrictEncode for (A, B, C) { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { writer.write_tuple::(|w| { Ok(w.write_field(&self.0)?.write_field(&self.1)?.write_field(&self.2)?.complete()) }) @@ -340,7 +341,7 @@ impl StrictType for [T; LEN fn strict_name() -> Option { None } } impl StrictEncode for [T; LEN] { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { for item in self { writer = item.strict_encode(writer)?; } @@ -372,7 +373,7 @@ impl StrictEncode for Array { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { self.as_inner().strict_encode(writer) } } @@ -391,7 +392,7 @@ impl StrictType for Confined StrictEncode for Confined { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { unsafe { writer .register_unicode(Sizing::new(MIN_LEN as u64, MAX_LEN as u64)) @@ -418,7 +419,7 @@ impl StrictType impl StrictEncode for Confined { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { unsafe { writer .register_list( @@ -460,7 +461,7 @@ impl StrictEncode for RString { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { debug_assert_ne!( MIN_LEN, 0, "Restricted string type can't have minimum length equal to zero" @@ -491,7 +492,7 @@ impl StrictType impl StrictEncode for Confined, MIN_LEN, MAX_LEN> { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { let sizing = Sizing::new(MIN_LEN as u64, MAX_LEN as u64); writer = unsafe { writer = writer.write_collection::, MIN_LEN, MAX_LEN>(self)?; @@ -526,7 +527,7 @@ impl StrictType impl StrictEncode for Confined, MIN_LEN, MAX_LEN> { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { let sizing = Sizing::new(MIN_LEN as u64, MAX_LEN as u64); writer = unsafe { writer = writer.write_collection::, MIN_LEN, MAX_LEN>(self)?; @@ -561,7 +562,7 @@ impl StrictType impl StrictEncode for Confined, MIN_LEN, MAX_LEN> { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { unsafe { writer = writer.write_collection::, MIN_LEN, MAX_LEN>(self)?; } @@ -602,7 +603,7 @@ impl< const MAX_LEN: usize, > StrictEncode for Confined, MIN_LEN, MAX_LEN> { - fn strict_encode(&self, mut writer: W) -> io::Result { + fn strict_encode(&self, mut writer: W) -> Result { unsafe { writer.raw_writer().write_raw_len::(self.len())?; } diff --git a/rust/src/error.rs b/rust/src/error.rs index e695e02..0a764e3 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -19,17 +19,36 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::io; -use std::ops::Range; +use core::ops::Range; -use amplify::{confinement, IoError}; +use amplify::confinement; + +#[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] +#[display(inner)] +// TODO: Replace with no-I/O variant from amplify when ready +pub struct ReadError(String); + +#[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] +#[display(inner)] +// TODO: Replace with no-I/O variant from amplify when ready +pub struct WriteError(String); + +#[cfg(feature = "std")] +impl From for ReadError { + fn from(err: std::io::Error) -> Self { Self(err.to_string()) } +} + +#[cfg(feature = "std")] +impl From for WriteError { + fn from(err: std::io::Error) -> Self { Self(err.to_string()) } +} #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] #[display(doc_comments)] pub enum DecodeError { + #[from] #[display(inner)] - #[from(io::Error)] - Io(IoError), + Read(ReadError), /// confinement requirements are not satisfied. Specifically, {0} #[from] @@ -40,7 +59,7 @@ pub enum DecodeError { /// string data are not in valid UTF-8 encoding.\nDetails: {0} #[from] - Utf8(std::string::FromUtf8Error), + Utf8(alloc::string::FromUtf8Error), /// string data are not in valid UTF-8 encoding.\nDetails: {0} #[from] @@ -77,9 +96,9 @@ pub enum DecodeError { #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] #[display(doc_comments)] pub enum SerializeError { + #[from] #[display(inner)] - #[from(io::Error)] - Io(IoError), + Write(WriteError), /// confinement requirements are not satisfied. Specifically, {0} #[from] @@ -89,9 +108,8 @@ pub enum SerializeError { #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] #[display(doc_comments)] pub enum DeserializeError { + #[from(ReadError)] #[display(inner)] - #[from] - #[from(io::Error)] Decode(DecodeError), /// data are not entirely consumed during strict deserialize operation diff --git a/rust/src/ident.rs b/rust/src/ident.rs index 7c41a23..fc9340d 100644 --- a/rust/src/ident.rs +++ b/rust/src/ident.rs @@ -19,7 +19,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::str::FromStr; +use core::str::FromStr; use amplify::Wrapper; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 40f9f65..9a08164 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -29,6 +29,16 @@ //missing_docs )] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +extern crate core; + +#[macro_use] +extern crate amplify; +#[cfg(feature = "serde")] +#[macro_use] +extern crate serde_crate as serde; #[cfg(feature = "derive")] pub use derive::{StrictDecode, StrictDumb, StrictEncode, StrictType}; @@ -39,12 +49,6 @@ pub use strict_encoding_derive as derive; #[cfg(not(feature = "derive"))] use strict_encoding_derive as derive; -#[macro_use] -extern crate amplify; -#[cfg(feature = "serde")] -#[macro_use] -extern crate serde_crate as serde; - #[macro_use] mod macros; mod types; @@ -62,7 +66,7 @@ pub mod stl; pub(crate) mod test; pub use embedded::{Byte, DecodeRawLe}; -pub use error::{DecodeError, DeserializeError, SerializeError}; +pub use error::{DecodeError, DeserializeError, ReadError, SerializeError, WriteError}; pub use ident::{FieldName, Ident, LibName, TypeName, VariantName, IDENT_MAX_LEN}; pub use primitives::{NumCls, NumInfo, NumSize, Primitive}; pub use reader::{ConfinedReader, StreamReader, StrictReader}; diff --git a/rust/src/macros.rs b/rust/src/macros.rs index b9ade44..dd3038a 100644 --- a/rust/src/macros.rs +++ b/rust/src/macros.rs @@ -43,7 +43,10 @@ macro_rules! impl_strict_newtype { const FIELD_COUNT: u8 = 1; } impl $crate::StrictEncode for $ty { - fn strict_encode(&self, writer: W) -> ::std::io::Result { + fn strict_encode( + &self, + writer: W, + ) -> Result { writer.write_newtype::(&self.0) } } @@ -79,7 +82,7 @@ macro_rules! impl_strict_struct { const ALL_FIELDS: &'static [&'static str] = &[$(stringify!($field)),+]; } impl $crate::StrictEncode for $ty { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { writer.write_struct::(|w| { Ok(w $(.write_field(fname!(stringify!($field)), &self.$field)?)+ diff --git a/rust/src/primitives.rs b/rust/src/primitives.rs index fb7e323..5e444a8 100644 --- a/rust/src/primitives.rs +++ b/rust/src/primitives.rs @@ -19,8 +19,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::fmt::{self, Display, Formatter, Write}; -use std::hash::Hash; +use core::fmt::{self, Display, Formatter, Write}; +use core::hash::Hash; use amplify::Wrapper; diff --git a/rust/src/reader.rs b/rust/src/reader.rs index 152c018..b88e26a 100644 --- a/rust/src/reader.rs +++ b/rust/src/reader.rs @@ -19,8 +19,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::io; - use crate::{ DecodeError, FieldName, ReadRaw, ReadStruct, ReadTuple, ReadUnion, StrictDecode, StrictEnum, StrictStruct, StrictSum, StrictTuple, StrictUnion, TypedRead, VariantName, diff --git a/rust/src/stl.rs b/rust/src/stl.rs index 0832581..301baaa 100644 --- a/rust/src/stl.rs +++ b/rust/src/stl.rs @@ -21,12 +21,12 @@ #![allow(non_camel_case_types, unused_imports)] -use std::borrow::Borrow; -use std::fmt::{Debug, Display, Formatter}; -use std::marker::PhantomData; -use std::ops::Deref; -use std::str::FromStr; -use std::{any, io}; +use core::any; +use core::borrow::Borrow; +use core::fmt::{self, Debug, Display, Formatter}; +use core::marker::PhantomData; +use core::ops::Deref; +use core::str::FromStr; use amplify::ascii::{AsAsciiStrError, AsciiChar, AsciiString, FromAsciiError}; use amplify::confinement; @@ -35,7 +35,7 @@ use amplify::num::{u1, u2, u3, u4, u5, u6, u7}; use crate::{ type_name, DecodeError, StrictDecode, StrictDumb, StrictEncode, StrictEnum, StrictSum, - StrictType, TypeName, TypedRead, TypedWrite, VariantError, LIB_NAME_STD, + StrictType, TypeName, TypedRead, TypedWrite, VariantError, WriteError, LIB_NAME_STD, }; // TODO: Move RString and related ASCII types to amplify library @@ -204,7 +204,7 @@ impl Debug for RString { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let c = type_name::(); let c1 = type_name::(); let c = if c == c1 { c.to_owned() } else { format!("{c1}, {c}") }; @@ -215,7 +215,7 @@ impl Display for RString { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.s, f) } + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.s, f) } } #[cfg(feature = "serde")] @@ -274,7 +274,7 @@ impl StrictType for bool { fn strict_name() -> Option { Some(tn!("Bool")) } } impl StrictEncode for bool { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { writer.write_enum::(Bool::from(self)) } } @@ -301,7 +301,7 @@ macro_rules! impl_u { fn strict_name() -> Option { Some(tn!(stringify!($ty))) } } impl StrictEncode for $inner { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { writer.write_enum::<$ty>($ty::try_from(self.to_u8()) .expect(concat!("broken", stringify!($inner), "type guarantees"))) } @@ -507,7 +507,9 @@ impl StrictSum for AsciiSym { } impl StrictEnum for AsciiSym {} impl StrictEncode for AsciiSym { - fn strict_encode(&self, writer: W) -> io::Result { writer.write_enum(*self) } + fn strict_encode(&self, writer: W) -> Result { + writer.write_enum(*self) + } } impl StrictDecode for AsciiSym { fn strict_decode(reader: &mut impl TypedRead) -> Result { @@ -648,7 +650,9 @@ impl StrictSum for AsciiPrintable { } impl StrictEnum for AsciiPrintable {} impl StrictEncode for AsciiPrintable { - fn strict_encode(&self, writer: W) -> io::Result { writer.write_enum(*self) } + fn strict_encode(&self, writer: W) -> Result { + writer.write_enum(*self) + } } impl StrictDecode for AsciiPrintable { fn strict_decode(reader: &mut impl TypedRead) -> Result { diff --git a/rust/src/test.rs b/rust/src/test.rs index c863f3b..ced2ffa 100644 --- a/rust/src/test.rs +++ b/rust/src/test.rs @@ -19,8 +19,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::fmt::Debug; -use std::io::BufRead; +use core::fmt::Debug; use amplify::confinement::Confined; diff --git a/rust/src/traits.rs b/rust/src/traits.rs index 7347572..7e6ab47 100644 --- a/rust/src/traits.rs +++ b/rust/src/traits.rs @@ -19,15 +19,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::io::{BufRead, Seek}; -use std::marker::PhantomData; -use std::{fs, io}; +use core::marker::PhantomData; use amplify::confinement::{Collection, Confined}; use amplify::num::u24; use amplify::Wrapper; -use super::{DecodeError, DecodeRawLe, VariantName}; +use super::{DecodeError, DecodeRawLe, ReadError, VariantName, WriteError}; use crate::reader::StreamReader; use crate::writer::StreamWriter; use crate::{ @@ -38,11 +36,14 @@ use crate::{ pub trait TypedParent: Sized {} pub trait WriteRaw { - fn write_raw(&mut self, bytes: impl AsRef<[u8]>) -> io::Result<()>; - fn write_raw_array(&mut self, raw: [u8; LEN]) -> io::Result<()> { + fn write_raw( + &mut self, + bytes: impl AsRef<[u8]>, + ) -> Result<(), WriteError>; + fn write_raw_array(&mut self, raw: [u8; LEN]) -> Result<(), WriteError> { self.write_raw::(raw) } - fn write_raw_len(&mut self, len: usize) -> io::Result<()> { + fn write_raw_len(&mut self, len: usize) -> Result<(), WriteError> { match MAX_LEN { tiny if tiny <= u8::MAX as usize => self.write_raw_array((len as u8).to_le_bytes()), small if small <= u16::MAX as usize => self.write_raw_array((len as u16).to_le_bytes()), @@ -57,7 +58,10 @@ pub trait WriteRaw { } impl WriteRaw for &mut T { - fn write_raw(&mut self, bytes: impl AsRef<[u8]>) -> io::Result<()> { + fn write_raw( + &mut self, + bytes: impl AsRef<[u8]>, + ) -> Result<(), WriteError> { (*self).write_raw::(bytes) } } @@ -74,19 +78,19 @@ pub trait TypedWrite: Sized { fn write_union( self, - inner: impl FnOnce(Self::UnionDefiner) -> io::Result, - ) -> io::Result; - fn write_enum(self, value: T) -> io::Result + inner: impl FnOnce(Self::UnionDefiner) -> Result, + ) -> Result; + fn write_enum(self, value: T) -> Result where u8: From; fn write_tuple( self, - inner: impl FnOnce(Self::TupleWriter) -> io::Result, - ) -> io::Result; + inner: impl FnOnce(Self::TupleWriter) -> Result, + ) -> Result; fn write_struct( self, - inner: impl FnOnce(Self::StructWriter) -> io::Result, - ) -> io::Result; - fn write_newtype(self, value: &impl StrictEncode) -> io::Result { + inner: impl FnOnce(Self::StructWriter) -> Result, + ) -> Result; + fn write_newtype(self, value: &impl StrictEncode) -> Result { self.write_tuple::(|writer| Ok(writer.write_field(value)?.complete())) } @@ -129,7 +133,7 @@ pub trait TypedWrite: Sized { unsafe fn write_string( mut self, bytes: impl AsRef<[u8]>, - ) -> io::Result { + ) -> Result { self.raw_writer().write_raw_len::(bytes.as_ref().len())?; self.raw_writer().write_raw::(bytes)?; Ok(self) @@ -140,7 +144,7 @@ pub trait TypedWrite: Sized { unsafe fn write_collection( mut self, col: &Confined, - ) -> io::Result + ) -> Result where for<'a> &'a C: IntoIterator, for<'a> <&'a C as IntoIterator>::Item: StrictEncode, @@ -156,9 +160,9 @@ pub trait TypedWrite: Sized { } pub trait ReadRaw { - fn read_raw(&mut self, len: usize) -> io::Result>; + fn read_raw(&mut self, len: usize) -> Result, ReadError>; - fn read_raw_array(&mut self) -> io::Result<[u8; LEN]>; + fn read_raw_array(&mut self) -> Result<[u8; LEN], ReadError>; fn read_raw_len(&mut self) -> Result { Ok(match MAX_LEN { @@ -173,11 +177,11 @@ pub trait ReadRaw { } impl ReadRaw for &mut T { - fn read_raw(&mut self, len: usize) -> io::Result> { + fn read_raw(&mut self, len: usize) -> Result, ReadError> { (*self).read_raw::(len) } - fn read_raw_array(&mut self) -> io::Result<[u8; LEN]> { + fn read_raw_array(&mut self) -> Result<[u8; LEN], ReadError> { (*self).read_raw_array::() } } @@ -237,7 +241,7 @@ pub trait DefineTuple: Sized { pub trait WriteTuple: Sized { type Parent: TypedParent; - fn write_field(self, value: &impl StrictEncode) -> io::Result; + fn write_field(self, value: &impl StrictEncode) -> Result; fn complete(self) -> Self::Parent; } @@ -253,7 +257,7 @@ pub trait DefineStruct: Sized { pub trait WriteStruct: Sized { type Parent: TypedParent; - fn write_field(self, name: FieldName, value: &impl StrictEncode) -> io::Result; + fn write_field(self, name: FieldName, value: &impl StrictEncode) -> Result; fn complete(self) -> Self::Parent; } @@ -270,7 +274,7 @@ pub trait DefineEnum: Sized { pub trait WriteEnum: Sized { type Parent: TypedWrite; - fn write_variant(self, name: VariantName) -> io::Result; + fn write_variant(self, name: VariantName) -> Result; fn complete(self) -> Self::Parent; } @@ -303,20 +307,24 @@ pub trait WriteUnion: Sized { type TupleWriter: WriteTuple; type StructWriter: WriteStruct; - fn write_unit(self, name: VariantName) -> io::Result; - fn write_newtype(self, name: VariantName, value: &impl StrictEncode) -> io::Result { + fn write_unit(self, name: VariantName) -> Result; + fn write_newtype( + self, + name: VariantName, + value: &impl StrictEncode, + ) -> Result { self.write_tuple(name, |writer| Ok(writer.write_field(value)?.complete())) } fn write_tuple( self, name: VariantName, - inner: impl FnOnce(Self::TupleWriter) -> io::Result, - ) -> io::Result; + inner: impl FnOnce(Self::TupleWriter) -> Result, + ) -> Result; fn write_struct( self, name: VariantName, - inner: impl FnOnce(Self::StructWriter) -> io::Result, - ) -> io::Result; + inner: impl FnOnce(Self::StructWriter) -> Result, + ) -> Result; fn complete(self) -> Self::Parent; } @@ -349,8 +357,8 @@ pub trait ReadUnion: Sized { } pub trait StrictEncode: StrictType { - fn strict_encode(&self, writer: W) -> io::Result; - fn strict_write(&self, writer: impl WriteRaw) -> io::Result<()> { + fn strict_encode(&self, writer: W) -> Result; + fn strict_write(&self, writer: impl WriteRaw) -> Result<(), WriteError> { let w = StrictWriter::with(writer); self.strict_encode(w)?; Ok(()) @@ -366,13 +374,13 @@ pub trait StrictDecode: StrictType { } impl StrictEncode for &T { - fn strict_encode(&self, writer: W) -> io::Result { + fn strict_encode(&self, writer: W) -> Result { (*self).strict_encode(writer) } } impl StrictEncode for PhantomData { - fn strict_encode(&self, writer: W) -> io::Result { Ok(writer) } + fn strict_encode(&self, writer: W) -> Result { Ok(writer) } } impl StrictDecode for PhantomData { @@ -380,7 +388,7 @@ impl StrictDecode for PhantomData { } pub trait StrictSerialize: StrictEncode { - fn strict_serialized_len(&self) -> io::Result { + fn strict_serialized_len(&self) -> Result { let counter = StrictWriter::counter::(); Ok(self.strict_encode(counter)?.unbox().unconfine().count) } @@ -393,11 +401,12 @@ pub trait StrictSerialize: StrictEncode { Confined::, 0, MAX>::try_from(data).map_err(SerializeError::from) } + #[cfg(feature = "std")] fn strict_serialize_to_file( &self, path: impl AsRef, ) -> Result<(), SerializeError> { - let file = fs::File::create(path)?; + let file = std::fs::File::create(path).map_err(WriteError::from)?; // TODO: Do FileReader let file = StrictWriter::with(StreamWriter::new::(file)); self.strict_encode(file)?; @@ -412,21 +421,27 @@ pub trait StrictDeserialize: StrictDecode { let mut reader = StrictReader::in_memory::(ast_data); let me = Self::strict_decode(&mut reader)?; let mut cursor = reader.into_cursor(); - if !cursor.fill_buf()?.is_empty() { + if !cursor.fill_buf().map_err(ReadError::from)?.is_empty() { return Err(DeserializeError::DataNotEntirelyConsumed); } Ok(me) } + #[cfg(feature = "std")] fn strict_deserialize_from_file( path: impl AsRef, ) -> Result { - let file = fs::File::open(path)?; + use std::io::Seek; + use std::{fs, io}; + + let file = fs::File::open(path).map_err(ReadError::from)?; // TODO: Do FileReader let mut reader = StrictReader::with(StreamReader::new::(file)); - let me = Self::strict_decode(&mut reader)?; + let me = Self::strict_decode(&mut reader).map_err(ReadError::from)?; let mut file = reader.unbox().unconfine(); - if file.stream_position()? != file.seek(io::SeekFrom::End(0))? { + if file.stream_position().map_err(ReadError::from)? + != file.seek(io::SeekFrom::End(0)).map_err(ReadError::from)? + { return Err(DeserializeError::DataNotEntirelyConsumed); } Ok(me) diff --git a/rust/src/types.rs b/rust/src/types.rs index 2c403a9..c7e5838 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -19,10 +19,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::any; -use std::collections::BTreeSet; -use std::fmt::{Debug, Display}; -use std::marker::PhantomData; +use alloc::collections::BTreeSet; +use core::any; +use core::fmt::{Debug, Display}; +use core::marker::PhantomData; use crate::{LibName, TypeName, VariantName}; diff --git a/rust/src/util.rs b/rust/src/util.rs index 4daa095..15efe84 100644 --- a/rust/src/util.rs +++ b/rust/src/util.rs @@ -19,10 +19,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::cmp::Ordering; -use std::fmt::{self, Display, Formatter}; -use std::hash::{Hash, Hasher}; -use std::io; +use core::cmp::Ordering; +use core::fmt::{self, Display, Formatter}; +use core::hash::{Hash, Hasher}; use crate::{ReadStruct, VariantName, WriteStruct, STRICT_TYPES_LIB}; diff --git a/rust/src/writer.rs b/rust/src/writer.rs index ded98fb..804c79e 100644 --- a/rust/src/writer.rs +++ b/rust/src/writer.rs @@ -19,13 +19,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::{BTreeMap, BTreeSet}; -use std::io; -use std::io::Sink; -use std::marker::PhantomData; +use alloc::collections::{BTreeMap, BTreeSet}; +use core::marker::PhantomData; use amplify::confinement::U64 as U64MAX; -use amplify::WriteCounter; +use amplify::{IoError, WriteCounter}; use crate::{ DefineEnum, DefineStruct, DefineTuple, DefineUnion, FieldName, LibName, StrictEncode, @@ -86,7 +84,10 @@ impl StreamWriter { } impl WriteRaw for StreamWriter { - fn write_raw(&mut self, bytes: impl AsRef<[u8]>) -> io::Result<()> { + fn write_raw( + &mut self, + bytes: impl AsRef<[u8]>, + ) -> Result<(), WriteError> { use io::Write; self.0.write_all(bytes.as_ref())?; Ok(()) @@ -135,13 +136,13 @@ impl TypedWrite for StrictWriter { fn write_union( self, - inner: impl FnOnce(Self::UnionDefiner) -> io::Result, - ) -> io::Result { + inner: impl FnOnce(Self::UnionDefiner) -> Result, + ) -> Result { let writer = UnionWriter::with::(self); inner(writer) } - fn write_enum(self, value: T) -> io::Result + fn write_enum(self, value: T) -> Result where u8: From { let mut writer = UnionWriter::with::(self); for (_, name) in T::ALL_VARIANTS { @@ -154,16 +155,16 @@ impl TypedWrite for StrictWriter { fn write_tuple( self, - inner: impl FnOnce(Self::TupleWriter) -> io::Result, - ) -> io::Result { + inner: impl FnOnce(Self::TupleWriter) -> Result, + ) -> Result { let writer = StructWriter::tuple::(self); inner(writer) } fn write_struct( self, - inner: impl FnOnce(Self::StructWriter) -> io::Result, - ) -> io::Result { + inner: impl FnOnce(Self::StructWriter) -> Result, + ) -> Result { let writer = StructWriter::structure::(self); inner(writer) } @@ -232,7 +233,7 @@ impl> StructWriter { pub fn into_parent(self) -> P { self.parent } - fn write_value(mut self, value: &impl StrictEncode) -> io::Result { + fn write_value(mut self, value: &impl StrictEncode) -> Result { let (mut writer, remnant) = self.parent.into_write_split(); writer = value.strict_encode(writer)?; self.parent = P::from_write_split(writer, remnant); @@ -264,7 +265,11 @@ impl> DefineStruct for StructWriter { impl> WriteStruct for StructWriter { type Parent = P; - fn write_field(mut self, _field: FieldName, value: &impl StrictEncode) -> io::Result { + fn write_field( + mut self, + _field: FieldName, + value: &impl StrictEncode, + ) -> Result { debug_assert!(self.tuple_fields.is_none(), "using struct method on tuple"); /* TODO: Propagate information about the fields at the parent debug_assert!( @@ -319,7 +324,7 @@ impl> DefineTuple for StructWriter { impl> WriteTuple for StructWriter { type Parent = P; - fn write_field(mut self, value: &impl StrictEncode) -> io::Result { + fn write_field(mut self, value: &impl StrictEncode) -> Result { /* TODO: Propagate information about number of fields at the parent assert!( self.tuple_fields.expect("writing tuple field to structure") as usize > self.cursor, @@ -425,7 +430,11 @@ impl UnionWriter { self } - fn _write_variant(mut self, name: VariantName, variant_type: VariantType) -> io::Result { + fn _write_variant( + mut self, + name: VariantName, + variant_type: VariantType, + ) -> Result { let (variant, t) = self.defined_variant.iter().find(|(f, _)| f.name == name).unwrap_or_else(|| { panic!("variant '{:#}' was not defined in '{}'", &name, self.name()) @@ -504,14 +513,14 @@ impl WriteUnion for UnionWriter { type TupleWriter = StructWriter; type StructWriter = StructWriter; - fn write_unit(self, name: VariantName) -> io::Result { + fn write_unit(self, name: VariantName) -> Result { self._write_variant(name, VariantType::Unit) } fn write_tuple( mut self, name: VariantName, - inner: impl FnOnce(Self::TupleWriter) -> io::Result, - ) -> io::Result { + inner: impl FnOnce(Self::TupleWriter) -> Result, + ) -> Result { self = self._write_variant(name, VariantType::Tuple)?; let writer = StructWriter::unnamed(self, true); inner(writer) @@ -519,8 +528,8 @@ impl WriteUnion for UnionWriter { fn write_struct( mut self, name: VariantName, - inner: impl FnOnce(Self::StructWriter) -> io::Result, - ) -> io::Result { + inner: impl FnOnce(Self::StructWriter) -> Result, + ) -> Result { self = self._write_variant(name, VariantType::Struct)?; let writer = StructWriter::unnamed(self, false); inner(writer) @@ -539,7 +548,7 @@ impl DefineEnum for UnionWriter { impl WriteEnum for UnionWriter { type Parent = StrictWriter; - fn write_variant(self, name: VariantName) -> io::Result { + fn write_variant(self, name: VariantName) -> Result { self._write_variant(name, VariantType::Unit) } fn complete(self) -> Self::Parent { self._complete_write() } diff --git a/rust/test_helpers/Cargo.toml b/rust/test_helpers/Cargo.toml index 89cb19b..251fa7f 100644 --- a/rust/test_helpers/Cargo.toml +++ b/rust/test_helpers/Cargo.toml @@ -16,4 +16,4 @@ readme = "../README.md" [dependencies] amplify = { workspace = true } -strict_encoding = { version = "2.8.0", path = ".." } +strict_encoding = { version = "3.0.0-alpha.1", path = ".." } diff --git a/rust/test_helpers/src/lib.rs b/rust/test_helpers/src/lib.rs index 1e24d32..b1860ce 100644 --- a/rust/test_helpers/src/lib.rs +++ b/rust/test_helpers/src/lib.rs @@ -87,8 +87,9 @@ extern crate amplify; use std::fmt::Debug; use std::io; -use amplify::IoError; -use strict_encoding::{DecodeError, StrictDecode, StrictEncode, StrictReader, StrictWriter}; +use strict_encoding::{ + DecodeError, StrictDecode, StrictEncode, StrictReader, StrictWriter, WriteError, +}; /// Failures happening during strict encoding tests of enum encodings. /// @@ -462,8 +463,9 @@ where T: StrictEncode + StrictDecode + PartialEq + Debug + Clone { /// Failure during encoding enum variant #[display("Failure during encoding: {0:?}")] + #[from] #[from(io::Error)] - EncoderFailure(#[doc = "Encoder error"] IoError), + EncoderFailure(#[doc = "Encoder error"] WriteError), /// Failure during decoding binary representation of enum variant #[display(