diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec012dd..5439090 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,6 +75,17 @@ jobs: env: MIRIFLAGS: -Zmiri-strict-provenance + no_std: + name: No default features (no_std) + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - run: cargo check --no-default-features + minimal: name: Minimal versions needs: pre_ci diff --git a/.gitignore b/.gitignore index f1c4fc0..84f4be8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /.cache/ /target/ /Cargo.lock +rust_out diff --git a/Cargo.toml b/Cargo.toml index 16918f5..90bc075 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,15 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/yaml/yaml-serde" rust-version = "1.82" +[features] +default = ["std"] +std = ["serde/std", "indexmap/std"] + [dependencies] -indexmap = "2.2.1" +indexmap = { version = "2.2.1", default-features = false } itoa = "1.0" ryu = "1.0" -serde = "1.0.195" +serde = { version = "1.0.195", default-features = false, features = ["alloc"] } libyaml-rs = "0.3" [dev-dependencies] diff --git a/src/de.rs b/src/de.rs index 1177e44..49532ef 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,3 +1,7 @@ +#[cfg(feature = "std")] +use alloc::boxed::Box; +use alloc::sync::Arc; +use alloc::{format, vec::Vec}; use crate::error::{self, Error, ErrorImpl}; use crate::libyaml::error::Mark; use crate::libyaml::parser::{MappingStart, Scalar, ScalarStyle, SequenceStart}; @@ -6,16 +10,17 @@ use crate::loader::{Document, Loader}; use crate::path::Path; use serde::de::value::StrDeserializer; use serde::de::{ - self, Deserialize, DeserializeOwned, DeserializeSeed, Expected, IgnoredAny, Unexpected, Visitor, + self, Deserialize, DeserializeSeed, Expected, IgnoredAny, Unexpected, Visitor, }; -use std::fmt; -use std::io; -use std::mem; -use std::num::ParseIntError; -use std::str; -use std::sync::Arc; +use core::fmt; +use core::mem; +use core::num::ParseIntError; +use core::str; -type Result = std::result::Result; +#[cfg(feature = "std")] +use serde::de::DeserializeOwned; + +type Result = core::result::Result; /// A structure that deserializes YAML into Rust values. /// @@ -62,7 +67,8 @@ pub struct Deserializer<'de> { pub(crate) enum Progress<'de> { Str(&'de str), Slice(&'de [u8]), - Read(Box), + #[cfg(feature = "std")] + Read(Box), Iterable(Loader<'de>), Document(Document<'de>), Fail(Arc), @@ -86,9 +92,10 @@ impl<'de> Deserializer<'de> { /// Reader-based deserializers do not support deserializing borrowed types /// like `&str`, since the `std::io::Read` trait has no non-copying methods /// -- everything it does involves copying bytes out of the data source. + #[cfg(feature = "std")] pub fn from_reader(rdr: R) -> Self where - R: io::Read + 'de, + R: crate::io::Read + 'de, { let progress = Progress::Read(Box::new(rdr)); Deserializer { progress } @@ -1817,9 +1824,10 @@ where /// is wrong with the data, for example required struct fields are missing from /// the YAML map or some number is too big to fit in the expected primitive /// type. +#[cfg(feature = "std")] pub fn from_reader(rdr: R) -> Result where - R: io::Read, + R: crate::io::Read, T: DeserializeOwned, { T::deserialize(Deserializer::from_reader(rdr)) diff --git a/src/error.rs b/src/error.rs index 9244480..812fcad 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,12 +1,13 @@ +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::sync::Arc; +use crate::io; use crate::libyaml::{emitter, error as libyaml}; use crate::path::Path; +use core::error::Error as StdError; +use core::fmt::{self, Debug, Display}; +use core::result; use serde::{de, ser}; -use std::error::Error as StdError; -use std::fmt::{self, Debug, Display}; -use std::io; -use std::result; -use std::string; -use std::sync::Arc; /// An error that happened serializing or deserializing YAML data. pub struct Error(Box); @@ -20,7 +21,7 @@ pub(crate) enum ErrorImpl { Libyaml(libyaml::Error), Io(io::Error), - FromUtf8(string::FromUtf8Error), + FromUtf8(alloc::string::FromUtf8Error), EndOfStream, MoreThanOneDocument, diff --git a/src/io.rs b/src/io.rs new file mode 100644 index 0000000..c94c497 --- /dev/null +++ b/src/io.rs @@ -0,0 +1,97 @@ +//! I/O traits abstracted over std and no_std. +//! +//! In std mode, re-exports from `std::io`. +//! In no_std mode, provides a minimal `Write` trait and error type. +//! +//! This follows the same pattern as `serde_json`: +//! + +#[cfg(feature = "std")] +pub use std::io::{Error, Read, Write}; + +#[cfg(feature = "std")] +pub(crate) fn sink() -> std::io::Sink { + std::io::sink() +} + +#[cfg(not(feature = "std"))] +pub use self::nostd::{Error, Write}; + +#[cfg(not(feature = "std"))] +pub(crate) use self::nostd::sink; + +#[cfg(not(feature = "std"))] +mod nostd { + use alloc::vec::Vec; + use core::fmt; + + pub type Result = core::result::Result; + + /// I/O error type for no_std mode. + pub struct Error; + + impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("I/O error") + } + } + + impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("io::Error") + } + } + + impl core::error::Error for Error {} + + /// Minimal `Write` trait for no_std environments. + pub trait Write { + /// Write all bytes from `buf` into the writer. + fn write_all(&mut self, buf: &[u8]) -> Result<()>; + /// Flush buffered data. + fn flush(&mut self) -> Result<()>; + } + + impl Write for &mut W { + #[inline] + fn write_all(&mut self, buf: &[u8]) -> Result<()> { + (**self).write_all(buf) + } + + #[inline] + fn flush(&mut self) -> Result<()> { + (**self).flush() + } + } + + pub fn sink() -> Sink { + Sink + } + + pub struct Sink; + + impl Write for Sink { + #[inline] + fn write_all(&mut self, _buf: &[u8]) -> Result<()> { + Ok(()) + } + + #[inline] + fn flush(&mut self) -> Result<()> { + Ok(()) + } + } + + impl Write for Vec { + #[inline] + fn write_all(&mut self, buf: &[u8]) -> Result<()> { + self.extend_from_slice(buf); + Ok(()) + } + + #[inline] + fn flush(&mut self) -> Result<()> { + Ok(()) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index c1272e9..5f909af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -119,6 +119,7 @@ //! } //! ``` +#![no_std] #![doc(html_root_url = "https://docs.rs/yaml_serde/0.10.4")] #![deny(missing_docs, unsafe_op_in_unsafe_fn)] // Suppressed clippy_pedantic lints @@ -164,7 +165,14 @@ clippy::must_use_candidate, )] -pub use crate::de::{from_reader, from_slice, from_str, Deserializer}; +#[cfg(feature = "std")] +extern crate std; + +extern crate alloc; + +#[cfg(feature = "std")] +pub use crate::de::from_reader; +pub use crate::de::{from_slice, from_str, Deserializer}; pub use crate::error::{Error, Location, Result}; pub use crate::ser::{to_string, to_writer, Serializer}; #[doc(inline)] @@ -175,6 +183,7 @@ pub use crate::mapping::Mapping; mod de; mod error; +pub mod io; mod libyaml; mod loader; pub mod mapping; @@ -186,6 +195,7 @@ pub mod with; // Prevent downstream code from implementing the Index trait. mod private { + use alloc::string::String; pub trait Sealed {} impl Sealed for usize {} impl Sealed for str {} diff --git a/src/libyaml/cstr.rs b/src/libyaml/cstr.rs index 2772e0f..1024372 100644 --- a/src/libyaml/cstr.rs +++ b/src/libyaml/cstr.rs @@ -1,8 +1,8 @@ -use std::fmt::{self, Debug, Display, Write as _}; -use std::marker::PhantomData; -use std::ptr::NonNull; -use std::slice; -use std::str; +use core::fmt::{self, Debug, Display, Write as _}; +use core::marker::PhantomData; +use core::ptr::NonNull; +use core::slice; +use core::str; #[derive(Copy, Clone)] pub(crate) struct CStr<'a> { diff --git a/src/libyaml/emitter.rs b/src/libyaml/emitter.rs index ebeac54..92b3833 100644 --- a/src/libyaml/emitter.rs +++ b/src/libyaml/emitter.rs @@ -1,10 +1,12 @@ +use alloc::boxed::Box; +use alloc::string::String; +use crate::io; use crate::libyaml; use crate::libyaml::util::Owned; -use std::ffi::c_void; -use std::io; -use std::mem::{self, MaybeUninit}; -use std::ptr::{self, addr_of_mut}; -use std::slice; +use core::ffi::c_void; +use core::mem::{self, MaybeUninit}; +use core::ptr::{self, addr_of_mut}; +use core::slice; use libyaml_rs as sys; #[derive(Debug)] @@ -181,7 +183,7 @@ impl<'a> Emitter<'a> { } pub fn into_inner(self) -> Box { - let sink = Box::new(io::sink()); + let sink: Box = Box::new(io::sink()); unsafe { mem::replace(&mut (*self.pin.ptr).write, sink) } } @@ -210,6 +212,7 @@ unsafe fn write_handler(data: *mut c_void, buffer: *mut u8, size: u64) -> i32 { } } + impl Drop for EmitterPinned<'_> { fn drop(&mut self) { unsafe { sys::yaml_emitter_delete(&raw mut self.sys) } diff --git a/src/libyaml/error.rs b/src/libyaml/error.rs index 55cdb98..1b4914e 100644 --- a/src/libyaml/error.rs +++ b/src/libyaml/error.rs @@ -1,10 +1,10 @@ use crate::libyaml::cstr::CStr; -use std::fmt::{self, Debug, Display}; -use std::mem::MaybeUninit; -use std::ptr::NonNull; +use core::fmt::{self, Debug, Display}; +use core::mem::MaybeUninit; +use core::ptr::NonNull; use libyaml_rs as sys; -pub(crate) type Result = std::result::Result; +pub(crate) type Result = core::result::Result; pub(crate) struct Error { kind: sys::yaml_error_type_t, diff --git a/src/libyaml/parser.rs b/src/libyaml/parser.rs index 1103ad2..05ac371 100644 --- a/src/libyaml/parser.rs +++ b/src/libyaml/parser.rs @@ -1,12 +1,13 @@ +use alloc::borrow::Cow; +use alloc::boxed::Box; use crate::libyaml::cstr::{self, CStr}; use crate::libyaml::error::{Error, Mark, Result}; use crate::libyaml::tag::Tag; use crate::libyaml::util::Owned; -use std::borrow::Cow; -use std::fmt::{self, Debug}; -use std::mem::MaybeUninit; -use std::ptr::{addr_of_mut, NonNull}; -use std::slice; +use core::fmt::{self, Debug}; +use core::mem::MaybeUninit; +use core::ptr::{addr_of_mut, NonNull}; +use core::slice; use libyaml_rs as sys; pub(crate) struct Parser<'input> { diff --git a/src/libyaml/tag.rs b/src/libyaml/tag.rs index 1f73185..ee36586 100644 --- a/src/libyaml/tag.rs +++ b/src/libyaml/tag.rs @@ -1,6 +1,7 @@ +use alloc::boxed::Box; use crate::libyaml::cstr; -use std::fmt::{self, Debug}; -use std::ops::Deref; +use core::fmt::{self, Debug}; +use core::ops::Deref; #[derive(Ord, PartialOrd, Eq, PartialEq)] pub(crate) struct Tag(pub(in crate::libyaml) Box<[u8]>); diff --git a/src/libyaml/util.rs b/src/libyaml/util.rs index 1f5010d..d98b1bc 100644 --- a/src/libyaml/util.rs +++ b/src/libyaml/util.rs @@ -1,7 +1,8 @@ -use std::marker::PhantomData; -use std::mem::{self, MaybeUninit}; -use std::ops::Deref; -use std::ptr::{addr_of, NonNull}; +use alloc::boxed::Box; +use core::marker::PhantomData; +use core::mem::{self, MaybeUninit}; +use core::ops::Deref; +use core::ptr::{addr_of, NonNull}; pub(crate) struct Owned { ptr: NonNull, diff --git a/src/loader.rs b/src/loader.rs index 5b395bd..7ab1bf5 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -1,10 +1,11 @@ +use alloc::borrow::Cow; +use alloc::collections::BTreeMap; +use alloc::sync::Arc; +use alloc::vec::Vec; use crate::de::{Event, Progress}; use crate::error::{self, Error, ErrorImpl, Result}; use crate::libyaml::error::Mark; use crate::libyaml::parser::{Event as YamlEvent, Parser}; -use std::borrow::Cow; -use std::collections::BTreeMap; -use std::sync::Arc; pub(crate) struct Loader<'input> { parser: Option>, @@ -23,6 +24,7 @@ impl<'input> Loader<'input> { let input = match progress { Progress::Str(s) => Cow::Borrowed(s.as_bytes()), Progress::Slice(bytes) => Cow::Borrowed(bytes), + #[cfg(feature = "std")] Progress::Read(mut rdr) => { let mut buffer = Vec::new(); if let Err(io_error) = rdr.read_to_end(&mut buffer) { diff --git a/src/mapping.rs b/src/mapping.rs index 2cff2ee..7e81a3c 100644 --- a/src/mapping.rs +++ b/src/mapping.rs @@ -1,18 +1,64 @@ //! A YAML mapping and its iterator types. +use alloc::string::String; +use alloc::vec::Vec; use crate::{private, Value}; +use core::cmp::Ordering; +use core::fmt::{self, Display}; +use core::hash::{Hash, Hasher}; +use core::mem; use indexmap::IndexMap; use serde::{Deserialize, Deserializer, Serialize}; -use std::cmp::Ordering; + +#[cfg(feature = "std")] use std::collections::hash_map::DefaultHasher; -use std::fmt::{self, Display}; -use std::hash::{Hash, Hasher}; -use std::mem; + +#[cfg(not(feature = "std"))] +mod fnv { + use core::hash::Hasher; + + pub struct FnvHasher(u64); + + impl FnvHasher { + pub fn new() -> Self { + FnvHasher(0xcbf2_9ce4_8422_2325) + } + } + + impl Hasher for FnvHasher { + fn finish(&self) -> u64 { + self.0 + } + + fn write(&mut self, bytes: &[u8]) { + for &b in bytes { + self.0 ^= u64::from(b); + self.0 = self.0.wrapping_mul(0x0100_0000_01b3); + } + } + } + + #[derive(Clone, Default)] + pub struct FnvBuildHasher; + + impl core::hash::BuildHasher for FnvBuildHasher { + type Hasher = FnvHasher; + fn build_hasher(&self) -> FnvHasher { + FnvHasher::new() + } + } +} + +#[cfg(feature = "std")] +type MapImpl = IndexMap; + +#[cfg(not(feature = "std"))] +type MapImpl = IndexMap; /// A YAML mapping in which the keys and values are both `yaml_serde::Value`. #[derive(Clone, Default, Eq, PartialEq)] pub struct Mapping { - map: IndexMap, + map: MapImpl, } impl Mapping { @@ -26,7 +72,10 @@ impl Mapping { #[inline] pub fn with_capacity(capacity: usize) -> Self { Mapping { + #[cfg(feature = "std")] map: IndexMap::with_capacity(capacity), + #[cfg(not(feature = "std"))] + map: IndexMap::with_capacity_and_hasher(capacity, fnv::FnvBuildHasher), } } @@ -389,7 +438,10 @@ impl Hash for Mapping { // Hash the kv pairs in a way that is not sensitive to their order. let mut xor = 0; for (k, v) in self { + #[cfg(feature = "std")] let mut hasher = DefaultHasher::new(); + #[cfg(not(feature = "std"))] + let mut hasher = fnv::FnvHasher::new(); k.hash(&mut hasher); v.hash(&mut hasher); xor ^= hasher.finish(); @@ -480,7 +532,7 @@ impl PartialOrd for Mapping { } } -impl std::ops::Index for Mapping +impl core::ops::Index for Mapping where I: Index, { @@ -493,7 +545,7 @@ where } } -impl std::ops::IndexMut for Mapping +impl core::ops::IndexMut for Mapping where I: Index, { diff --git a/src/number.rs b/src/number.rs index 8f91676..ab3aa2d 100644 --- a/src/number.rs +++ b/src/number.rs @@ -1,11 +1,11 @@ use crate::de; use crate::error::{self, Error, ErrorImpl}; +use core::cmp::Ordering; +use core::fmt::{self, Display}; +use core::hash::{Hash, Hasher}; +use core::str::FromStr; use serde::de::{Unexpected, Visitor}; use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer}; -use std::cmp::Ordering; -use std::fmt::{self, Display}; -use std::hash::{Hash, Hasher}; -use std::str::FromStr; /// Represents a YAML number, whether integer or floating point. #[derive(Clone, PartialEq, PartialOrd)] diff --git a/src/path.rs b/src/path.rs index c5be012..cb0f5fa 100644 --- a/src/path.rs +++ b/src/path.rs @@ -1,4 +1,4 @@ -use std::fmt::{self, Display}; +use core::fmt::{self, Display}; /// Path to the current value in the input, like `dependencies.serde.typo1`. #[derive(Copy, Clone)] diff --git a/src/ser.rs b/src/ser.rs index b46b1fc..c8c8c84 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -2,20 +2,24 @@ //! //! This module provides YAML serialization with the type `Serializer`. +use alloc::borrow::ToOwned; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; use crate::error::{self, Error, ErrorImpl}; +use crate::io; use crate::libyaml; use crate::libyaml::emitter::{Emitter, Event, Mapping, Scalar, ScalarStyle, Sequence}; use crate::value::tagged::{self, MaybeTag}; use serde::de::Visitor; use serde::ser::{self, Serializer as _}; -use std::fmt::{self, Display}; -use std::io; -use std::marker::PhantomData; -use std::mem; -use std::num; -use std::str; - -type Result = std::result::Result; +use core::fmt::{self, Display}; +use core::marker::PhantomData; +use core::mem; +use core::num; +use core::str; + +type Result = core::result::Result; /// A structure for serializing Rust values into YAML. /// diff --git a/src/value/de.rs b/src/value/de.rs index e044773..6cd331e 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -1,15 +1,19 @@ +use alloc::borrow::ToOwned; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; use crate::value::tagged::{self, TagStringVisitor}; use crate::value::TaggedValue; use crate::{number, Error, Mapping, Sequence, Value}; +use core::fmt; +use core::slice; use serde::de::value::{BorrowedStrDeserializer, StrDeserializer}; use serde::de::{ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, Expected, MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor, }; use serde::forward_to_deserialize_any; -use std::fmt; -use std::slice; -use std::vec; impl<'de> Deserialize<'de> for Value { fn deserialize(deserializer: D) -> Result diff --git a/src/value/debug.rs b/src/value/debug.rs index 891f8f7..3fddbc0 100644 --- a/src/value/debug.rs +++ b/src/value/debug.rs @@ -1,6 +1,6 @@ use crate::mapping::Mapping; use crate::value::{Number, Value}; -use std::fmt::{self, Debug, Display}; +use core::fmt::{self, Debug, Display}; impl Debug for Value { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/value/from.rs b/src/value/from.rs index 9f1b640..7c615f7 100644 --- a/src/value/from.rs +++ b/src/value/from.rs @@ -1,3 +1,5 @@ +use alloc::string::{String, ToString}; +use alloc::vec::Vec; use crate::{Mapping, Value}; // Implement a bunch of conversion to make it easier to create YAML values @@ -69,7 +71,7 @@ impl From<&str> for Value { } } -use std::borrow::Cow; +use alloc::borrow::Cow; impl<'a> From> for Value { /// Convert copy-on-write string to `Value` diff --git a/src/value/index.rs b/src/value/index.rs index dbb2094..1e9c595 100644 --- a/src/value/index.rs +++ b/src/value/index.rs @@ -1,7 +1,9 @@ +use alloc::borrow::ToOwned; +use alloc::string::String; use crate::mapping::Entry; use crate::{mapping, private, Mapping, Value}; -use std::fmt::{self, Debug}; -use std::ops; +use core::fmt::{self, Debug}; +use core::ops; /// A type that can be used to index into a `yaml_serde::Value`. See the `get` /// and `get_mut` methods of `Value`. diff --git a/src/value/mod.rs b/src/value/mod.rs index ccea74a..a35516c 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -8,11 +8,14 @@ mod partial_eq; mod ser; pub(crate) mod tagged; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; use crate::error::{self, Error, ErrorImpl}; +use core::hash::{Hash, Hasher}; +use core::mem; use serde::de::{Deserialize, DeserializeOwned, IntoDeserializer}; use serde::Serialize; -use std::hash::{Hash, Hasher}; -use std::mem; pub use self::index::Index; pub use self::ser::Serializer; diff --git a/src/value/partial_eq.rs b/src/value/partial_eq.rs index 999b109..260bd20 100644 --- a/src/value/partial_eq.rs +++ b/src/value/partial_eq.rs @@ -1,3 +1,4 @@ +use alloc::string::String; use crate::Value; impl PartialEq for Value { diff --git a/src/value/ser.rs b/src/value/ser.rs index ba37933..f9358ce 100644 --- a/src/value/ser.rs +++ b/src/value/ser.rs @@ -1,11 +1,14 @@ +use alloc::borrow::ToOwned; +use alloc::boxed::Box; +use alloc::string::ToString; use crate::error::{self, Error, ErrorImpl}; use crate::value::tagged::{self, MaybeTag}; use crate::value::{to_value, Mapping, Number, Sequence, Tag, TaggedValue, Value}; +use core::fmt::Display; +use core::mem; use serde::ser::{self, Serialize}; -use std::fmt::Display; -use std::mem; -type Result = std::result::Result; +type Result = core::result::Result; impl Serialize for Value { fn serialize(&self, serializer: S) -> Result diff --git a/src/value/tagged.rs b/src/value/tagged.rs index 7952d35..87dc9da 100644 --- a/src/value/tagged.rs +++ b/src/value/tagged.rs @@ -1,16 +1,18 @@ +use alloc::borrow::ToOwned; +use alloc::string::String; use crate::value::de::{MapDeserializer, MapRefDeserializer, SeqDeserializer, SeqRefDeserializer}; use crate::value::Value; use crate::Error; +use core::cmp::Ordering; +use core::fmt::{self, Debug, Display}; +use core::hash::{Hash, Hasher}; +use core::mem; use serde::de::value::{BorrowedStrDeserializer, StrDeserializer}; use serde::de::{ Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, VariantAccess, Visitor, }; use serde::forward_to_deserialize_any; use serde::ser::{Serialize, SerializeMap, Serializer}; -use std::cmp::Ordering; -use std::fmt::{self, Debug, Display}; -use std::hash::{Hash, Hasher}; -use std::mem; /// A representation of YAML's `!Tag` syntax, used for enums. /// diff --git a/src/with.rs b/src/with.rs index 6ce3558..83e1778 100644 --- a/src/with.rs +++ b/src/with.rs @@ -73,7 +73,10 @@ /// value: 1 /// ``` pub mod singleton_map { + use alloc::borrow::ToOwned; + use alloc::string::String; use crate::value::{Mapping, Sequence, Value}; + use core::fmt::{self, Display}; use serde::de::{ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, IgnoredAny, MapAccess, Unexpected, VariantAccess, Visitor, @@ -81,7 +84,6 @@ pub mod singleton_map { use serde::ser::{ self, Serialize, SerializeMap, SerializeStructVariant, SerializeTupleVariant, Serializer, }; - use std::fmt::{self, Display}; #[allow(missing_docs)] pub fn serialize(value: &T, serializer: S) -> Result @@ -933,7 +935,11 @@ pub mod singleton_map { /// } /// ``` pub mod singleton_map_recursive { + use alloc::borrow::ToOwned; + use alloc::string::String; + use alloc::vec::Vec; use crate::value::{Mapping, Sequence, Value}; + use core::fmt::{self, Display}; use serde::de::{ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, IgnoredAny, MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor, @@ -942,7 +948,6 @@ pub mod singleton_map_recursive { self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, Serializer, }; - use std::fmt::{self, Display}; #[allow(missing_docs)] pub fn serialize(value: &T, serializer: S) -> Result