diff --git a/duper-python/src/de.rs b/duper-python/src/de.rs index 1fc928d..cab4a61 100644 --- a/duper-python/src/de.rs +++ b/duper-python/src/de.rs @@ -67,7 +67,7 @@ impl<'py> DuperVisitor for Visitor<'py> { fn visit_array<'a>( &mut self, identifier: Option<&duper::DuperIdentifier<'a>>, - array: &duper::DuperArray<'a>, + array: &[duper::DuperValue<'a>], ) -> Self::Value { let vec: PyResult> = array .iter() @@ -84,7 +84,7 @@ impl<'py> DuperVisitor for Visitor<'py> { fn visit_tuple<'a>( &mut self, identifier: Option<&duper::DuperIdentifier<'a>>, - tuple: &duper::DuperTuple<'a>, + tuple: &[duper::DuperValue<'a>], ) -> Self::Value { let vec: PyResult> = tuple .iter() @@ -101,10 +101,10 @@ impl<'py> DuperVisitor for Visitor<'py> { fn visit_string<'a>( &mut self, identifier: Option<&duper::DuperIdentifier<'a>>, - string: &duper::DuperString<'a>, + string: &'a str, ) -> Self::Value { Ok(VisitorValue { - value: PyString::new(self.py, &string.clone().into_inner()).into_any(), + value: PyString::new(self.py, &string).into_any(), duper: identifier .map(|identifier| Duper::from_identifier(identifier)?.into_pyobject(self.py)) .transpose()?, @@ -114,25 +114,22 @@ impl<'py> DuperVisitor for Visitor<'py> { fn visit_bytes<'a>( &mut self, identifier: Option<&duper::DuperIdentifier<'a>>, - bytes: &duper::DuperBytes<'a>, + bytes: &'a [u8], ) -> Self::Value { Ok(VisitorValue { - value: PyBytes::new(self.py, &bytes.clone().into_inner()).into_any(), + value: PyBytes::new(self.py, &bytes).into_any(), duper: identifier .map(|identifier| Duper::from_identifier(identifier)?.into_pyobject(self.py)) .transpose()?, }) } - fn visit_temporal<'a>( - &mut self, - identifier: Option<&duper::DuperIdentifier<'a>>, - temporal: &DuperTemporal<'a>, - ) -> Self::Value { + fn visit_temporal<'a>(&mut self, temporal: &DuperTemporal<'a>) -> Self::Value { Ok(VisitorValue { value: TemporalString::from_temporal(temporal)?.into_bound_py_any(self.py)?, - duper: identifier - .map(|identifier| Duper::from_identifier(identifier)?.into_pyobject(self.py)) + duper: temporal + .identifier() + .map(|identifier| Duper::from_identifier(&identifier)?.into_pyobject(self.py)) .transpose()?, }) } diff --git a/duper-python/src/ser/mod.rs b/duper-python/src/ser/mod.rs index c3f5f13..bf58b81 100644 --- a/duper-python/src/ser/mod.rs +++ b/duper-python/src/ser/mod.rs @@ -1,9 +1,6 @@ use std::borrow::Cow; -use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperInner, DuperKey, DuperObject, DuperString, - DuperTuple, DuperValue, -}; +use duper::{DuperIdentifier, DuperKey, DuperObject, DuperValue}; use pyo3::{BoundObject, exceptions::PyValueError, prelude::*, types::*}; use well_known_type::WellKnownType; @@ -17,44 +14,42 @@ pub(crate) fn serialize_pyany<'py>(obj: Bound<'py, PyAny>) -> PyResult() { - Ok(DuperValue { + Ok(DuperValue::Object { identifier: None, - inner: DuperInner::Object( - DuperObject::try_from(serialize_pydict(obj.cast()?)?) - .expect("no duplicate keys in dict"), - ), + inner: DuperObject::try_from(serialize_pydict(obj.cast()?)?) + .expect("no duplicate keys in dict"), }) } else if obj.is_instance_of::() { - Ok(DuperValue { + Ok(DuperValue::Array { identifier: None, - inner: DuperInner::Array(DuperArray::from(serialize_pyiter(obj.try_iter()?)?)), + inner: serialize_pyiter(obj.try_iter()?)?, }) } else if obj.is_instance_of::() { - Ok(DuperValue { + Ok(DuperValue::Array { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Set")).expect("valid identifier"), ), - inner: DuperInner::Array(DuperArray::from(serialize_pyiter(obj.try_iter()?)?)), + inner: serialize_pyiter(obj.try_iter()?)?, }) } else if obj.is_instance_of::() { - Ok(DuperValue { + Ok(DuperValue::Tuple { identifier: None, - inner: DuperInner::Tuple(DuperTuple::from(serialize_pyiter(obj.try_iter()?)?)), + inner: serialize_pyiter(obj.try_iter()?)?, }) } else if obj.is_instance_of::() { - Ok(DuperValue { + Ok(DuperValue::Bytes { identifier: None, - inner: DuperInner::Bytes(DuperBytes::from(Cow::Owned(obj.extract()?))), + inner: Cow::Owned(obj.extract()?), }) } else if obj.is_instance_of::() { - Ok(DuperValue { + Ok(DuperValue::String { identifier: None, - inner: DuperInner::String(DuperString::from(Cow::Owned(obj.extract()?))), + inner: Cow::Owned(obj.extract()?), }) } else if obj.is_instance_of::() { - Ok(DuperValue { + Ok(DuperValue::Boolean { identifier: None, - inner: DuperInner::Boolean(obj.extract()?), + inner: obj.extract()?, }) } else if obj.is_instance_of::() { let identifier = { @@ -69,35 +64,32 @@ pub(crate) fn serialize_pyany<'py>(obj: Bound<'py, PyAny>) -> PyResult() { - Ok(DuperValue { + Ok(DuperValue::Float { identifier: None, - inner: DuperInner::Float(obj.extract()?), + inner: obj.extract()?, }) } else if obj.is_none() { - Ok(DuperValue { - identifier: None, - inner: DuperInner::Null, - }) + Ok(DuperValue::Null { identifier: None }) } // Handle sequences else if let Ok(pyiter) = obj.try_iter() { let identifier = serialize_pyclass_identifier(&obj)?; - Ok(DuperValue { + Ok(DuperValue::Array { identifier, - inner: DuperInner::Array(DuperArray::from(serialize_pyiter(pyiter.into_bound())?)), + inner: serialize_pyiter(pyiter.into_bound())?, }) } // Handle unknown types @@ -107,18 +99,16 @@ pub(crate) fn serialize_pyany<'py>(obj: Bound<'py, PyAny>) -> PyResult(format!( diff --git a/duper-python/src/ser/well_known_type.rs b/duper-python/src/ser/well_known_type.rs index 925a5ad..c54c63d 100644 --- a/duper-python/src/ser/well_known_type.rs +++ b/duper-python/src/ser/well_known_type.rs @@ -1,14 +1,11 @@ use std::borrow::Cow; -use duper::{ - DuperArray, DuperIdentifier, DuperInner, DuperKey, DuperObject, DuperString, DuperTemporal, - DuperValue, -}; +use duper::{DuperIdentifier, DuperKey, DuperObject, DuperTemporal, DuperValue}; use pyo3::{exceptions::PyValueError, prelude::*, types::*}; use crate::{ Duper, - ser::{serialize_pyany, serialize_pyclass_identifier}, + ser::{serialize_pyany, serialize_pyclass_identifier, serialize_pydict}, temporal::TemporalString, }; @@ -92,15 +89,15 @@ pub(crate) enum WellKnownType<'py> { // re Pattern(Bound<'py, PyAny>), // temporal string - TemporalStringInstant(duper::DuperTemporal<'static>), - TemporalStringZonedDateTime(duper::DuperTemporal<'static>), - TemporalStringPlainDate(duper::DuperTemporal<'static>), - TemporalStringPlainTime(duper::DuperTemporal<'static>), - TemporalStringPlainDateTime(duper::DuperTemporal<'static>), - TemporalStringPlainYearMonth(duper::DuperTemporal<'static>), - TemporalStringPlainMonthDay(duper::DuperTemporal<'static>), - TemporalStringDuration(duper::DuperTemporal<'static>), - TemporalString(duper::DuperTemporal<'static>), + TemporalStringInstant(duper::DuperTemporalInstant<'static>), + TemporalStringZonedDateTime(duper::DuperTemporalZonedDateTime<'static>), + TemporalStringPlainDate(duper::DuperTemporalPlainDate<'static>), + TemporalStringPlainTime(duper::DuperTemporalPlainTime<'static>), + TemporalStringPlainDateTime(duper::DuperTemporalPlainDateTime<'static>), + TemporalStringPlainYearMonth(duper::DuperTemporalPlainYearMonth<'static>), + TemporalStringPlainMonthDay(duper::DuperTemporalPlainMonthDay<'static>), + TemporalStringDuration(duper::DuperTemporalDuration<'static>), + TemporalUnspecifiedString(duper::DuperTemporalUnspecified<'static>), // uuid Uuid(Bound<'py, PyAny>), } @@ -326,46 +323,42 @@ impl<'py> WellKnownType<'py> { if let Ok(value) = value.cast::() { let temporal = &value.get().temporal; match temporal { - DuperTemporal::Instant(_) => { - return Ok(Some(WellKnownType::TemporalStringInstant(temporal.clone()))); + DuperTemporal::Instant { inner } => { + return Ok(Some(WellKnownType::TemporalStringInstant(inner.clone()))); } - DuperTemporal::ZonedDateTime(_) => { + DuperTemporal::ZonedDateTime { inner } => { return Ok(Some(WellKnownType::TemporalStringZonedDateTime( - temporal.clone(), + inner.clone(), ))); } - DuperTemporal::PlainDate(_) => { - return Ok(Some(WellKnownType::TemporalStringPlainDate( - temporal.clone(), - ))); + DuperTemporal::PlainDate { inner } => { + return Ok(Some(WellKnownType::TemporalStringPlainDate(inner.clone()))); } - DuperTemporal::PlainTime(_) => { - return Ok(Some(WellKnownType::TemporalStringPlainTime( - temporal.clone(), - ))); + DuperTemporal::PlainTime { inner } => { + return Ok(Some(WellKnownType::TemporalStringPlainTime(inner.clone()))); } - DuperTemporal::PlainDateTime(_) => { + DuperTemporal::PlainDateTime { inner } => { return Ok(Some(WellKnownType::TemporalStringPlainDateTime( - temporal.clone(), + inner.clone(), ))); } - DuperTemporal::PlainYearMonth(_) => { + DuperTemporal::PlainYearMonth { inner } => { return Ok(Some(WellKnownType::TemporalStringPlainYearMonth( - temporal.clone(), + inner.clone(), ))); } - DuperTemporal::PlainMonthDay(_) => { + DuperTemporal::PlainMonthDay { inner } => { return Ok(Some(WellKnownType::TemporalStringPlainMonthDay( - temporal.clone(), + inner.clone(), ))); } - DuperTemporal::Duration(_) => { - return Ok(Some(WellKnownType::TemporalStringDuration( - temporal.clone(), - ))); + DuperTemporal::Duration { inner } => { + return Ok(Some(WellKnownType::TemporalStringDuration(inner.clone()))); } - DuperTemporal::Unspecified(_) => { - return Ok(Some(WellKnownType::TemporalString(temporal.clone()))); + DuperTemporal::Unspecified { inner, .. } => { + return Ok(Some(WellKnownType::TemporalUnspecifiedString( + inner.clone(), + ))); } } } @@ -375,28 +368,27 @@ impl<'py> WellKnownType<'py> { pub(crate) fn serialize(self) -> PyResult> { match self { // bson - WellKnownType::BsonObjectId(value) => Ok(DuperValue { + WellKnownType::BsonObjectId(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("ObjectId")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), // collections - WellKnownType::Deque(value) => Ok(DuperValue { + WellKnownType::Deque(value) => Ok(DuperValue::Array { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Deque")).expect("valid identifier"), ), - inner: DuperInner::Array(DuperArray::from( - value - .try_iter()? - .map(|elem| -> PyResult> { serialize_pyany(elem?) }) - .collect::>>()?, - )), + inner: value + .try_iter()? + .map(|elem| -> PyResult> { serialize_pyany(elem?) }) + .collect::>>()?, }), // dataclasses - WellKnownType::Dataclass(value) => Ok(DuperValue { + WellKnownType::Dataclass(value) => Ok(DuperValue::Object { identifier: serialize_pyclass_identifier(&value)?, - inner: serialize_pyany(value.getattr("__dict__")?)?.inner, + inner: DuperObject::try_from(serialize_pydict(value.getattr("__dict__")?.cast()?)?) + .expect("no duplicate keys in __dict__"), }), // datetime WellKnownType::DateTime(value) => Ok({ @@ -404,521 +396,476 @@ impl<'py> WellKnownType<'py> { Cow::Owned(value.call_method0("isoformat")?.extract()?); let tzinfo = value.getattr("tzinfo")?; if tzinfo.is_none() || tzinfo.getattr("utcoffset")?.call1((value,))?.is_none() { - DuperValue { - identifier: Some( - DuperIdentifier::try_from(Cow::Borrowed("PlainDateTime")) - .expect("valid identifier"), - ), - inner: DuperInner::Temporal( - DuperTemporal::try_plain_date_time_from(datetime).map_err(|err| { - PyValueError::new_err(format!( - "Failed to parse Temporal value: {err}" - )) - })?, - ), - } + DuperValue::try_plain_date_time_from(datetime).map_err(|err| { + PyValueError::new_err(format!("Failed to parse Temporal value: {err}")) + })? } else { - DuperValue { - identifier: Some( - DuperIdentifier::try_from(Cow::Borrowed("Instant")) - .expect("valid identifier"), - ), - inner: DuperInner::Temporal( - DuperTemporal::try_instant_from(datetime).map_err(|err| { - PyValueError::new_err(format!( - "Failed to parse Temporal value: {err}" - )) - })?, - ), - } - } - }), - WellKnownType::TimeDelta(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from(Cow::Borrowed("Duration")).expect("valid identifier"), - ), - inner: { - let py = value.py(); - let datetime_module = py.import("datetime")?; - let pydantic_module = py.import("pydantic")?; - let adapter = pydantic_module - .getattr("TypeAdapter")? - .call1((datetime_module.getattr("timedelta")?,))?; - let kwargs = PyDict::new(py); - kwargs.set_item("mode", "json")?; - let dump = adapter - .getattr("dump_python")? - .call((value,), Some(&kwargs))?; - DuperInner::Temporal( - DuperTemporal::try_duration_from(Cow::Owned(dump.extract()?)).map_err( - |err| { - PyValueError::new_err(format!( - "Failed to parse Temporal value: {err}" - )) - }, - )?, - ) - }, - }), - WellKnownType::Date(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from(Cow::Borrowed("PlainDate")) - .expect("valid identifier"), - ), - inner: DuperInner::Temporal( - DuperTemporal::try_plain_date_from(Cow::Owned( - value.call_method0("isoformat")?.extract()?, - )) - .map_err(|err| { + DuperValue::try_instant_from(datetime).map_err(|err| { PyValueError::new_err(format!("Failed to parse Temporal value: {err}")) - })?, - ), - }), - WellKnownType::Time(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from(Cow::Borrowed("PlainTime")) - .expect("valid identifier"), - ), - inner: DuperInner::Temporal( - DuperTemporal::try_plain_time_from(Cow::Owned( - value.call_method0("isoformat")?.extract()?, - )) - .map_err(|err| { + })? + } + }), + WellKnownType::TimeDelta(value) => { + let py = value.py(); + let datetime_module = py.import("datetime")?; + let pydantic_module = py.import("pydantic")?; + let adapter = pydantic_module + .getattr("TypeAdapter")? + .call1((datetime_module.getattr("timedelta")?,))?; + let kwargs = PyDict::new(py); + kwargs.set_item("mode", "json")?; + let dump = adapter + .getattr("dump_python")? + .call((value,), Some(&kwargs))?; + let duration: String = dump.extract()?; + Ok( + DuperValue::try_duration_from(Cow::Owned(duration)).map_err(|err| { PyValueError::new_err(format!("Failed to parse Temporal value: {err}")) })?, - ), - }), + ) + } + WellKnownType::Date(value) => Ok(DuperValue::try_plain_date_from(Cow::Owned( + value.call_method0("isoformat")?.extract()?, + )) + .map_err(|err| { + PyValueError::new_err(format!("Failed to parse Temporal value: {err}")) + })?), + WellKnownType::Time(value) => Ok(DuperValue::try_plain_time_from(Cow::Owned( + value.call_method0("isoformat")?.extract()?, + )) + .map_err(|err| { + PyValueError::new_err(format!("Failed to parse Temporal value: {err}")) + })?), // decimal - WellKnownType::Decimal(value) => Ok(DuperValue { + WellKnownType::Decimal(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Decimal")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), // enum - WellKnownType::Enum(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from(Cow::Borrowed("IPv4Address")) - .expect("valid identifier"), - ), - inner: serialize_pyany(value.getattr("value")?)?.inner, - }), + WellKnownType::Enum(value) => Ok(serialize_pyany(value.getattr("value")?)? + .with_identifier(serialize_pyclass_identifier(&value)?) + .map_err(|err| { + PyValueError::new_err(format!("Invalid identifier for Enum: {err}")) + })?), // ipaddress - WellKnownType::IPv4Address(value) => Ok(DuperValue { + WellKnownType::IPv4Address(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPv4Address")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPv4Interface(value) => Ok(DuperValue { + WellKnownType::IPv4Interface(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPv4Interface")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPv4Network(value) => Ok(DuperValue { + WellKnownType::IPv4Network(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPv4Network")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPv6Address(value) => Ok(DuperValue { + WellKnownType::IPv6Address(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPv6Address")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPv6Interface(value) => Ok(DuperValue { + WellKnownType::IPv6Interface(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPv6Interface")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPv6Network(value) => Ok(DuperValue { + WellKnownType::IPv6Network(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPv6Network")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), // pathlib - WellKnownType::Path(value) => Ok(DuperValue { + WellKnownType::Path(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Path")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::PosixPath(value) => Ok(DuperValue { + WellKnownType::PosixPath(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("PosixPath")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::WindowsPath(value) => Ok(DuperValue { + WellKnownType::WindowsPath(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("WindowsPath")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::PurePath(value) => Ok(DuperValue { + WellKnownType::PurePath(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("PurePath")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::PurePosixPath(value) => Ok(DuperValue { + WellKnownType::PurePosixPath(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("PurePosixPath")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::PureWindowsPath(value) => Ok(DuperValue { + WellKnownType::PureWindowsPath(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("PureWindowsPath")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), // pydantic WellKnownType::BaseModel(value) => serialize_pydantic_model(value), - WellKnownType::ByteSize(value) => Ok(DuperValue { - identifier: Some( + WellKnownType::ByteSize(value) => Ok(serialize_pyany(value.call_method0("__int__")?)? + .with_identifier(Some( DuperIdentifier::try_from(Cow::Borrowed("ByteSize")).expect("valid identifier"), - ), - inner: serialize_pyany(value.call_method0("__int__")?)?.inner, - }), + )) + .map_err(|err| { + PyValueError::new_err(format!("Invalid identifier for ByteSize: {err}")) + })?), // pydantic network types - WellKnownType::AnyUrl(value) => Ok(DuperValue { + WellKnownType::AnyUrl(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("AnyUrl")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::AnyHttpUrl(value) => Ok(DuperValue { + WellKnownType::AnyHttpUrl(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("AnyHttpUrl")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::HttpUrl(value) => Ok(DuperValue { + WellKnownType::HttpUrl(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("HttpUrl")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::AnyWebsocketUrl(value) => Ok(DuperValue { + WellKnownType::AnyWebsocketUrl(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("AnyWebsocketUrl")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::WebsocketUrl(value) => Ok(DuperValue { + WellKnownType::WebsocketUrl(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("WebsocketUrl")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::FileUrl(value) => Ok(DuperValue { + WellKnownType::FileUrl(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("FileUrl")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::FtpUrl(value) => Ok(DuperValue { + WellKnownType::FtpUrl(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("FtpUrl")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::PostgresDsn(value) => Ok(DuperValue { + WellKnownType::PostgresDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("PostgresDsn")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::CockroachDsn(value) => Ok(DuperValue { + WellKnownType::CockroachDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("CockroachDsn")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::AmqpDsn(value) => Ok(DuperValue { + WellKnownType::AmqpDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("AmqpDsn")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::RedisDsn(value) => Ok(DuperValue { + WellKnownType::RedisDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("RedisDsn")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::MongoDsn(value) => Ok(DuperValue { + WellKnownType::MongoDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("MongoDsn")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::KafkaDsn(value) => Ok(DuperValue { + WellKnownType::KafkaDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("KafkaDsn")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::NatsDsn(value) => Ok(DuperValue { + WellKnownType::NatsDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("NatsDsn")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::MySQLDsn(value) => Ok(DuperValue { + WellKnownType::MySQLDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("MySQLDsn")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::MariaDBDsn(value) => Ok(DuperValue { + WellKnownType::MariaDBDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("MariaDBDsn")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::ClickHouseDsn(value) => Ok(DuperValue { + WellKnownType::ClickHouseDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("ClickHouseDsn")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::SnowflakeDsn(value) => Ok(DuperValue { + WellKnownType::SnowflakeDsn(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("SnowflakeDsn")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::EmailStr(value) => Ok(DuperValue { + WellKnownType::EmailStr(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("EmailStr")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::NameEmail(value) => Ok(DuperValue { + WellKnownType::NameEmail(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("NameEmail")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPvAnyAddress(value) => Ok(DuperValue { + WellKnownType::IPvAnyAddress(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPvAnyAddress")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPvAnyInterface(value) => Ok(DuperValue { + WellKnownType::IPvAnyInterface(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPvAnyInterface")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::IPvAnyNetwork(value) => Ok(DuperValue { + WellKnownType::IPvAnyNetwork(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("IPvAnyNetwork")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), // pydantic extra types - WellKnownType::Color(value) => Ok(DuperValue { + WellKnownType::Color(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Color")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::CountryAlpha2(value) => Ok(DuperValue { + WellKnownType::CountryAlpha2(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("CountryAlpha2")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::CountryAlpha3(value) => Ok(DuperValue { + WellKnownType::CountryAlpha3(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("CountryAlpha3")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::CountryNumericCode(value) => Ok(DuperValue { + WellKnownType::CountryNumericCode(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("CountryNumericCode")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::CountryShortName(value) => Ok(DuperValue { + WellKnownType::CountryShortName(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("CountryShortName")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::CronStr(value) => Ok(DuperValue { + WellKnownType::CronStr(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("CronStr")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::PaymentCardNumber(value) => Ok(DuperValue { + WellKnownType::PaymentCardNumber(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("PaymentCardNumber")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::AbaRoutingNumber(value) => Ok(DuperValue { + WellKnownType::AbaRoutingNumber(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("ABARoutingNumber")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::LanguageAlpha2(value) => Ok(DuperValue { + WellKnownType::LanguageAlpha2(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("LanguageAlpha2")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::LanguageName(value) => Ok(DuperValue { + WellKnownType::LanguageName(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("LanguageName")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::Iso639_3(value) => Ok(DuperValue { + WellKnownType::Iso639_3(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("ISO639-3")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::Iso639_5(value) => Ok(DuperValue { + WellKnownType::Iso639_5(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("ISO639-5")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::Iso15924(value) => Ok(DuperValue { + WellKnownType::Iso15924(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("ISO15924")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::S3Path(value) => Ok(DuperValue { + WellKnownType::S3Path(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("S3Path")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::SemanticVersion(value) => Ok(DuperValue { + WellKnownType::SemanticVersion(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("SemanticVersion")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::TimeZoneName(value) => Ok(DuperValue { + WellKnownType::TimeZoneName(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("TimeZoneName")) .expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), - WellKnownType::Ulid(value) => Ok(DuperValue { + WellKnownType::Ulid(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Ulid")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), // re - WellKnownType::Pattern(value) => Ok(DuperValue { + WellKnownType::Pattern(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Pattern")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned( - value.getattr("pattern")?.extract()?, - ))), + inner: Cow::Owned(value.getattr("pattern")?.extract()?), }), // temporal string - WellKnownType::TemporalStringInstant(value) => Ok(DuperValue { - identifier: Some(DuperIdentifier::try_from("Instant").expect("valid identifier")), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalStringZonedDateTime(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from("ZonedDateTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalStringPlainDate(value) => Ok(DuperValue { - identifier: Some(DuperIdentifier::try_from("PlainDate").expect("valid identifier")), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalStringPlainTime(value) => Ok(DuperValue { - identifier: Some(DuperIdentifier::try_from("PlainTime").expect("valid identifier")), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalStringPlainDateTime(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainDateTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalStringPlainYearMonth(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainYearMonth").expect("valid identifier"), - ), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalStringPlainMonthDay(value) => Ok(DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainMonthDay").expect("valid identifier"), - ), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalStringDuration(value) => Ok(DuperValue { - identifier: Some(DuperIdentifier::try_from("Duration").expect("valid identifier")), - inner: DuperInner::Temporal(value), - }), - WellKnownType::TemporalString(value) => Ok(DuperValue { - identifier: None, - inner: DuperInner::Temporal(value), - }), + WellKnownType::TemporalStringInstant(value) => { + Ok(DuperValue::Temporal(DuperTemporal::Instant { + inner: value, + })) + } + WellKnownType::TemporalStringZonedDateTime(value) => { + Ok(DuperValue::Temporal(DuperTemporal::ZonedDateTime { + inner: value, + })) + } + WellKnownType::TemporalStringPlainDate(value) => { + Ok(DuperValue::Temporal(DuperTemporal::PlainDate { + inner: value, + })) + } + WellKnownType::TemporalStringPlainTime(value) => { + Ok(DuperValue::Temporal(DuperTemporal::PlainTime { + inner: value, + })) + } + WellKnownType::TemporalStringPlainDateTime(value) => { + Ok(DuperValue::Temporal(DuperTemporal::PlainDateTime { + inner: value, + })) + } + WellKnownType::TemporalStringPlainYearMonth(value) => { + Ok(DuperValue::Temporal(DuperTemporal::PlainYearMonth { + inner: value, + })) + } + WellKnownType::TemporalStringPlainMonthDay(value) => { + Ok(DuperValue::Temporal(DuperTemporal::PlainMonthDay { + inner: value, + })) + } + WellKnownType::TemporalStringDuration(value) => { + Ok(DuperValue::Temporal(DuperTemporal::Duration { + inner: value, + })) + } + WellKnownType::TemporalUnspecifiedString(value) => { + Ok(DuperValue::Temporal(DuperTemporal::Unspecified { + identifier: None, + inner: value, + })) + } // uuid - WellKnownType::Uuid(value) => Ok(DuperValue { + WellKnownType::Uuid(value) => Ok(DuperValue::String { identifier: Some( DuperIdentifier::try_from(Cow::Borrowed("Uuid")).expect("valid identifier"), ), - inner: DuperInner::String(DuperString::from(Cow::Owned(value.str()?.extract()?))), + inner: Cow::Owned(value.str()?.extract()?), }), } } @@ -930,7 +877,7 @@ fn serialize_pydantic_model<'py>(obj: Bound<'py, PyAny>) -> PyResult() { let field_dict = model_fields.cast::()?; - let fields: PyResult> = field_dict + let fields: PyResult, DuperValue<'_>)>> = field_dict .iter() .map(|(field_name, field_info)| { let field_name: &Bound<'py, PyString> = field_name.cast()?; @@ -944,7 +891,7 @@ fn serialize_pydantic_model<'py>(obj: Bound<'py, PyAny>) -> PyResult false, }) .transpose()?; - let identifier = duper_metadata.map_or(duper_value.identifier, |duper| { + let identifier = duper_metadata.map_or(duper_value.identifier(), |duper| { duper .cast::() .expect("checked Duper instance") @@ -954,10 +901,9 @@ fn serialize_pydantic_model<'py>(obj: Bound<'py, PyAny>) -> PyResult(obj: Bound<'py, PyAny>) -> PyResult>() { - Ok(DuperValue { + Ok(DuperValue::Object { identifier: Some( DuperIdentifier::try_from_lossy(Cow::Owned(title.to_string())).map_err( |error| { - PyErr::new::(format!( + PyValueError::new_err(format!( "Invalid identifier: {title} ({error})" )) }, )?, ), - inner: DuperInner::Object( - DuperObject::try_from(fields?) - .expect("no duplicate keys in Pydantic model"), - ), + inner: DuperObject::try_from(fields?) + .expect("no duplicate keys in Pydantic model"), }) } else { - Ok(DuperValue { + Ok(DuperValue::Object { identifier: None, - inner: DuperInner::Object( - DuperObject::try_from(fields?) - .expect("no duplicate keys in Pydantic model"), - ), + inner: DuperObject::try_from(fields?) + .expect("no duplicate keys in Pydantic model"), }) } } else { - Ok(DuperValue { + Ok(DuperValue::Object { identifier: serialize_pyclass_identifier(&obj)?, - inner: DuperInner::Object( - DuperObject::try_from(fields?).expect("no duplicate keys in Pydantic model"), - ), + inner: DuperObject::try_from(fields?).expect("no duplicate keys in Pydantic model"), }) } } else { diff --git a/duper-python/src/temporal.rs b/duper-python/src/temporal.rs index e41b013..a68820f 100644 --- a/duper-python/src/temporal.rs +++ b/duper-python/src/temporal.rs @@ -90,13 +90,12 @@ impl TemporalString { "Unknown TemporalString type {typ}" ))); } - None => duper::DuperTemporal::try_unspecified_from(Cow::Owned(value)).map_err( - |err| { + None => duper::DuperTemporal::try_unspecified_from(None, Cow::Owned(value)) + .map_err(|err| { PyValueError::new_err(format!( "Failed to parse Unspecified Temporal value: {err}" )) - }, - )?, + })?, }, }) } @@ -104,15 +103,15 @@ impl TemporalString { #[getter] fn r#type(&self) -> Option<&str> { match self.temporal { - duper::DuperTemporal::Instant(_) => Some("Instant"), - duper::DuperTemporal::ZonedDateTime(_) => Some("ZonedDateTime"), - duper::DuperTemporal::PlainDate(_) => Some("PlainDate"), - duper::DuperTemporal::PlainTime(_) => Some("PlainTime"), - duper::DuperTemporal::PlainDateTime(_) => Some("PlainDateTime"), - duper::DuperTemporal::PlainYearMonth(_) => Some("PlainYearMonth"), - duper::DuperTemporal::PlainMonthDay(_) => Some("PlainMonthDay"), - duper::DuperTemporal::Duration(_) => Some("Duration"), - duper::DuperTemporal::Unspecified(_) => None, + duper::DuperTemporal::Instant { .. } => Some("Instant"), + duper::DuperTemporal::ZonedDateTime { .. } => Some("ZonedDateTime"), + duper::DuperTemporal::PlainDate { .. } => Some("PlainDate"), + duper::DuperTemporal::PlainTime { .. } => Some("PlainTime"), + duper::DuperTemporal::PlainDateTime { .. } => Some("PlainDateTime"), + duper::DuperTemporal::PlainYearMonth { .. } => Some("PlainYearMonth"), + duper::DuperTemporal::PlainMonthDay { .. } => Some("PlainMonthDay"), + duper::DuperTemporal::Duration { .. } => Some("Duration"), + duper::DuperTemporal::Unspecified { .. } => None, } } @@ -132,19 +131,14 @@ impl TemporalString { Ok(temporal.get().clone()) } else if let Ok(value) = value.extract() { Ok(Self { - temporal: duper::DuperTemporal::try_unspecified_from(Cow::Owned(value)).map_err( - |err| { + temporal: duper::DuperTemporal::try_unspecified_from(None, Cow::Owned(value)) + .map_err(|err| { PyValueError::new_err(format!( "Failed to parse Unspecified Temporal value: {err}" )) - }, - )?, + })?, }) - } else if let Ok(duper::DuperValue { - identifier: _, - inner: duper::DuperInner::Temporal(temporal), - }) = serialize_pyany(value.clone()) - { + } else if let Ok(duper::DuperValue::Temporal(temporal)) = serialize_pyany(value.clone()) { Ok(Self { temporal: temporal.static_clone(), }) @@ -173,29 +167,35 @@ impl TemporalString { let py = args.py(); let value = args.extract::<(TemporalString,)>()?.0; match value.temporal { - duper::DuperTemporal::Instant(inner) - | duper::DuperTemporal::PlainDateTime(inner) => { + duper::DuperTemporal::Instant { inner } => { + let datetime = py.import("datetime")?.getattr("datetime")?; + Ok(datetime + .getattr("fromisoformat")? + .call1((inner.as_ref(),))? + .unbind()) + } + duper::DuperTemporal::PlainDateTime { inner } => { let datetime = py.import("datetime")?.getattr("datetime")?; Ok(datetime .getattr("fromisoformat")? .call1((inner.as_ref(),))? .unbind()) } - duper::DuperTemporal::PlainDate(inner) => { + duper::DuperTemporal::PlainDate { inner } => { let date = py.import("datetime")?.getattr("date")?; Ok(date .getattr("fromisoformat")? .call1((inner.as_ref(),))? .unbind()) } - duper::DuperTemporal::PlainTime(inner) => { + duper::DuperTemporal::PlainTime { inner } => { let time = py.import("datetime")?.getattr("time")?; Ok(time .getattr("fromisoformat")? .call1((inner.as_ref(),))? .unbind()) } - duper::DuperTemporal::Duration(inner) => { + duper::DuperTemporal::Duration { inner } => { let timedelta = py.import("datetime")?.getattr("timedelta")?; let adapter = py .import("pydantic")? diff --git a/duper/src/ast.rs b/duper/src/ast.rs index 7ff57ff..9948778 100644 --- a/duper/src/ast.rs +++ b/duper/src/ast.rs @@ -94,7 +94,7 @@ pub struct DuperKey<'a>(pub(crate) Cow<'a, str>); #[derive(Debug, Clone)] pub struct DuperObject<'a>(pub(crate) IndexMap, DuperValue<'a>>); -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum DuperTemporal<'a> { /// A Temporal Instant: `Instant('...')` Instant { @@ -457,6 +457,10 @@ impl<'a> DuperKey<'a> { pub fn into_inner(self) -> Cow<'a, str> { self.0 } + + pub fn static_clone(&self) -> DuperKey<'static> { + DuperKey(Cow::Owned(self.0.clone().into_owned())) + } } impl<'a> AsRef for DuperKey<'a> { @@ -587,6 +591,21 @@ impl<'a> DuperValue<'a> { } } + pub fn identifier(&self) -> Option> { + match self { + DuperValue::Temporal(inner) => inner.identifier(), + DuperValue::Object { identifier, .. } + | DuperValue::Array { identifier, .. } + | DuperValue::Tuple { identifier, .. } + | DuperValue::String { identifier, .. } + | DuperValue::Bytes { identifier, .. } + | DuperValue::Integer { identifier, .. } + | DuperValue::Float { identifier, .. } + | DuperValue::Boolean { identifier, .. } + | DuperValue::Null { identifier } => identifier.as_ref().cloned(), + } + } + pub fn with_identifier( self, identifier: Option>, @@ -760,6 +779,10 @@ impl<'a> DuperObject<'a> { self.0.iter() } + pub fn get<'b>(&'b self, key: &'b DuperKey<'_>) -> Option<&'b DuperValue<'a>> { + self.0.get(key) + } + /// Create a valid object from the provided [`Vec`], dropping any duplicate keys /// and keeping the first one. pub fn from_lossy(value: Vec<(DuperKey<'a>, DuperValue<'a>)>) -> Self { diff --git a/duper/src/serde/temporal.rs b/duper/src/serde/temporal.rs index 3e3e776..ced7108 100644 --- a/duper/src/serde/temporal.rs +++ b/duper/src/serde/temporal.rs @@ -51,6 +51,7 @@ pub const FIELD_VALUE: &str = "$__duper_private_value"; /// let deserialized: MyType<'_> = duper::serde::de::from_string(&output).unwrap(); /// assert!(matches!(deserialized.inner, TemporalString::PlainYearMonth(_))); /// ``` +#[derive(Debug)] pub enum TemporalString<'a> { Instant(DuperTemporalInstant<'a>), ZonedDateTime(DuperTemporalZonedDateTime<'a>), diff --git a/duper_uniffi/src/parse.rs b/duper_uniffi/src/parse.rs index fcb0532..4b32908 100644 --- a/duper_uniffi/src/parse.rs +++ b/duper_uniffi/src/parse.rs @@ -1,7 +1,4 @@ -use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperObject, DuperString, DuperTemporal, DuperTuple, - visitor::DuperVisitor, -}; +use duper::{DuperIdentifier, DuperObject, DuperTemporal, visitor::DuperVisitor}; use crate::{DuperObjectEntry, DuperValue}; @@ -31,7 +28,7 @@ impl DuperVisitor for UniffiVisitor { fn visit_array<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - array: &DuperArray<'a>, + array: &[duper::DuperValue<'a>], ) -> Self::Value { let mut value = Vec::with_capacity(array.len()); for val in array.iter() { @@ -46,7 +43,7 @@ impl DuperVisitor for UniffiVisitor { fn visit_tuple<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - tuple: &DuperTuple<'a>, + tuple: &[duper::DuperValue<'a>], ) -> Self::Value { let mut value = Vec::with_capacity(tuple.len()); for val in tuple.iter() { @@ -61,18 +58,18 @@ impl DuperVisitor for UniffiVisitor { fn visit_string<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - string: &DuperString<'a>, + string: &'a str, ) -> Self::Value { DuperValue::String { identifier: identifier.map(|identifier| identifier.as_ref().to_string()), - value: string.as_ref().to_string(), + value: string.to_string(), } } fn visit_bytes<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - bytes: &DuperBytes<'a>, + bytes: &'a [u8], ) -> Self::Value { DuperValue::Bytes { identifier: identifier.map(|identifier| identifier.as_ref().to_string()), @@ -80,13 +77,11 @@ impl DuperVisitor for UniffiVisitor { } } - fn visit_temporal<'a>( - &mut self, - identifier: Option<&DuperIdentifier<'a>>, - temporal: &DuperTemporal<'a>, - ) -> Self::Value { + fn visit_temporal<'a>(&mut self, temporal: &DuperTemporal<'a>) -> Self::Value { DuperValue::Temporal { - identifier: identifier.map(|identifier| identifier.as_ref().to_string()), + identifier: temporal + .identifier() + .map(|identifier| identifier.as_ref().to_string()), value: temporal.as_ref().to_string(), } } diff --git a/duper_uniffi/src/serialize.rs b/duper_uniffi/src/serialize.rs index ab9616b..47ce121 100644 --- a/duper_uniffi/src/serialize.rs +++ b/duper_uniffi/src/serialize.rs @@ -1,54 +1,47 @@ use std::borrow::Cow; -use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperInner, DuperKey, DuperObject, DuperString, - DuperTemporal, DuperTuple, DuperValue, -}; +use duper::{DuperIdentifier, DuperKey, DuperObject, DuperTemporal, DuperValue}; use crate::{DuperError, DuperObjectEntry, DuperValue as Value}; impl Value { pub(crate) fn serialize(self) -> Result, DuperError> { match self { - Value::Object { identifier, value } => Ok(DuperValue { + Value::Object { identifier, value } => Ok(DuperValue::Object { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Object(DuperObject::try_from( + inner: DuperObject::try_from( value .into_iter() .map(|DuperObjectEntry { key, value }| { value.serialize().map(|val| (DuperKey::from(key), val)) }) .collect::, _>>()?, - )?), + )?, }), - Value::Array { identifier, value } => Ok(DuperValue { + Value::Array { identifier, value } => Ok(DuperValue::Array { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Array(DuperArray::from( - value - .into_iter() - .map(|val| val.serialize()) - .collect::, _>>()?, - )), + inner: value + .into_iter() + .map(|val| val.serialize()) + .collect::, _>>()?, }), - Value::Tuple { identifier, value } => Ok(DuperValue { + Value::Tuple { identifier, value } => Ok(DuperValue::Tuple { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Tuple(DuperTuple::from( - value - .into_iter() - .map(|val| val.serialize()) - .collect::, _>>()?, - )), + inner: value + .into_iter() + .map(|val| val.serialize()) + .collect::, _>>()?, }), - Value::String { identifier, value } => Ok(DuperValue { + Value::String { identifier, value } => Ok(DuperValue::String { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::String(DuperString::from(value)), + inner: Cow::Owned(value), }), - Value::Bytes { identifier, value } => Ok(DuperValue { + Value::Bytes { identifier, value } => Ok(DuperValue::Bytes { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Bytes(DuperBytes::from(value)), + inner: Cow::Owned(value), }), - Value::Temporal { identifier, value } => Ok(DuperValue { - inner: DuperInner::Temporal(match identifier.as_ref().map(AsRef::as_ref) { + Value::Temporal { identifier, value } => Ok(DuperValue::Temporal( + match identifier.as_ref().map(AsRef::as_ref) { Some("Instant") => DuperTemporal::try_instant_from(Cow::Owned(value))?, Some("ZonedDateTime") => { DuperTemporal::try_zoned_date_time_from(Cow::Owned(value))? @@ -65,25 +58,30 @@ impl Value { DuperTemporal::try_plain_month_day_from(Cow::Owned(value))? } Some("Duration") => DuperTemporal::try_duration_from(Cow::Owned(value))?, - Some(_) | None => DuperTemporal::try_unspecified_from(Cow::Owned(value))?, - }), - identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - }), - Value::Integer { identifier, value } => Ok(DuperValue { + identifier => DuperTemporal::try_unspecified_from( + identifier + .map(|identifier| { + DuperIdentifier::try_from(Cow::Owned(identifier.to_string())) + }) + .transpose()?, + Cow::Owned(value), + )?, + }, + )), + Value::Integer { identifier, value } => Ok(DuperValue::Integer { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Integer(value), + inner: value, }), - Value::Float { identifier, value } => Ok(DuperValue { + Value::Float { identifier, value } => Ok(DuperValue::Float { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Float(value), + inner: value, }), - Value::Boolean { identifier, value } => Ok(DuperValue { + Value::Boolean { identifier, value } => Ok(DuperValue::Boolean { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Boolean(value), + inner: value, }), - Value::Null { identifier } => Ok(DuperValue { + Value::Null { identifier } => Ok(DuperValue::Null { identifier: identifier.map(DuperIdentifier::try_from).transpose()?, - inner: DuperInner::Null, }), } } diff --git a/duper_website/src/visitor/saphyr.rs b/duper_website/src/visitor/saphyr.rs index 140f0b8..35a4816 100644 --- a/duper_website/src/visitor/saphyr.rs +++ b/duper_website/src/visitor/saphyr.rs @@ -1,8 +1,5 @@ use base64::{Engine, prelude::BASE64_STANDARD}; -use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperObject, DuperString, DuperTemporal, DuperTuple, - visitor::DuperVisitor, -}; +use duper::{DuperIdentifier, DuperObject, DuperTemporal, DuperValue, visitor::DuperVisitor}; use saphyr::{ScalarOwned, ScalarStyle, Tag, YamlOwned}; // A visitor that serializes Duper into a Saphyr YAML value. @@ -33,7 +30,7 @@ impl DuperVisitor for SaphyrVisitor { fn visit_array<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - array: &DuperArray<'a>, + array: &[DuperValue<'a>], ) -> Self::Value { let sequence: Result<_, _> = array.iter().map(|value| value.accept(self)).collect(); Ok(YamlOwned::Sequence(sequence?)) @@ -42,7 +39,7 @@ impl DuperVisitor for SaphyrVisitor { fn visit_tuple<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - tuple: &DuperTuple<'a>, + tuple: &[DuperValue<'a>], ) -> Self::Value { let sequence: Result<_, _> = tuple.iter().map(|value| value.accept(self)).collect(); Ok(YamlOwned::Sequence(sequence?)) @@ -51,20 +48,18 @@ impl DuperVisitor for SaphyrVisitor { fn visit_string<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - string: &DuperString<'a>, + string: &'a str, ) -> Self::Value { - Ok(YamlOwned::Value(ScalarOwned::String( - string.as_ref().to_string(), - ))) + Ok(YamlOwned::Value(ScalarOwned::String(string.to_string()))) } fn visit_bytes<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - bytes: &DuperBytes<'a>, + bytes: &'a [u8], ) -> Self::Value { Ok(YamlOwned::Representation( - BASE64_STANDARD.encode(bytes.as_ref()), + BASE64_STANDARD.encode(bytes), ScalarStyle::DoubleQuoted, Some(Tag { handle: String::new(), @@ -73,11 +68,7 @@ impl DuperVisitor for SaphyrVisitor { )) } - fn visit_temporal<'a>( - &mut self, - _identifier: Option<&DuperIdentifier<'a>>, - temporal: &DuperTemporal<'a>, - ) -> Self::Value { + fn visit_temporal<'a>(&mut self, temporal: &DuperTemporal<'a>) -> Self::Value { Ok(YamlOwned::Representation( temporal.as_ref().to_string(), ScalarStyle::Plain, diff --git a/duper_website/src/visitor/serde.rs b/duper_website/src/visitor/serde.rs index 508d896..b16651d 100644 --- a/duper_website/src/visitor/serde.rs +++ b/duper_website/src/visitor/serde.rs @@ -1,7 +1,8 @@ +use std::borrow::Cow; + use base64::{Engine, prelude::BASE64_STANDARD}; use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperInner, DuperKey, DuperObject, DuperString, - DuperTemporal, DuperTuple, DuperValue, visitor::DuperVisitor, + DuperIdentifier, DuperKey, DuperObject, DuperTemporal, DuperValue, visitor::DuperVisitor, }; // A visitor that simplifies Duper values for Serde serializers. @@ -19,74 +20,70 @@ impl DuperVisitor for SerdeVisitor { for (key, value) in object.iter() { new_object.push((DuperKey::from(key.as_ref().to_owned()), value.accept(self))); } - DuperValue { + DuperValue::Object { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::Object( - DuperObject::try_from(new_object).expect("object keys are unchanged"), - ), + inner: DuperObject::try_from(new_object).expect("object keys are unchanged"), } } fn visit_array<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - array: &DuperArray<'a>, + array: &[DuperValue<'a>], ) -> Self::Value { let mut new_array = Vec::with_capacity(array.len()); for value in array.iter() { new_array.push(value.accept(self)); } - DuperValue { + DuperValue::Array { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::Array(DuperArray::from(new_array)), + inner: new_array, } } fn visit_tuple<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - tuple: &DuperTuple<'a>, + tuple: &[DuperValue<'a>], ) -> Self::Value { let mut new_tuple = Vec::with_capacity(tuple.len()); for value in tuple.iter() { new_tuple.push(value.accept(self)); } - DuperValue { + DuperValue::Tuple { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::Tuple(DuperTuple::from(new_tuple)), + inner: new_tuple, } } fn visit_string<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - string: &DuperString<'a>, + string: &'a str, ) -> Self::Value { - DuperValue { + DuperValue::String { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::String(DuperString::from(string.as_ref().to_owned())), + inner: Cow::Owned(string.to_string()), } } fn visit_bytes<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - bytes: &DuperBytes<'a>, + bytes: &'a [u8], ) -> Self::Value { - DuperValue { + DuperValue::String { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::String(DuperString::from(BASE64_STANDARD.encode(bytes.as_ref()))), + inner: Cow::Owned(BASE64_STANDARD.encode(bytes)), } } - fn visit_temporal<'a>( - &mut self, - identifier: Option<&DuperIdentifier<'a>>, - temporal: &DuperTemporal<'a>, - ) -> Self::Value { - DuperValue { - identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::String(DuperString::from(temporal.as_ref().to_owned())), + fn visit_temporal<'a>(&mut self, temporal: &DuperTemporal<'a>) -> Self::Value { + DuperValue::String { + identifier: temporal + .identifier() + .map(|identifier| identifier.static_clone()), + inner: Cow::Owned(temporal.as_ref().to_string()), } } @@ -95,9 +92,9 @@ impl DuperVisitor for SerdeVisitor { identifier: Option<&DuperIdentifier<'a>>, integer: i64, ) -> Self::Value { - DuperValue { + DuperValue::Integer { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::Integer(integer), + inner: integer, } } @@ -106,9 +103,9 @@ impl DuperVisitor for SerdeVisitor { identifier: Option<&DuperIdentifier<'a>>, float: f64, ) -> Self::Value { - DuperValue { + DuperValue::Float { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::Float(float), + inner: float, } } @@ -117,16 +114,15 @@ impl DuperVisitor for SerdeVisitor { identifier: Option<&DuperIdentifier<'a>>, boolean: bool, ) -> Self::Value { - DuperValue { + DuperValue::Boolean { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::Boolean(boolean), + inner: boolean, } } fn visit_null<'a>(&mut self, identifier: Option<&DuperIdentifier<'a>>) -> Self::Value { - DuperValue { + DuperValue::Null { identifier: identifier.map(|identifier| identifier.static_clone()), - inner: DuperInner::Null, } } } diff --git a/duper_website/src/visitor/toml.rs b/duper_website/src/visitor/toml.rs index 0328950..b297ede 100644 --- a/duper_website/src/visitor/toml.rs +++ b/duper_website/src/visitor/toml.rs @@ -1,10 +1,7 @@ use std::str::FromStr; use base64::{Engine, prelude::BASE64_STANDARD}; -use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperObject, DuperString, DuperTemporal, DuperTuple, - visitor::DuperVisitor, -}; +use duper::{DuperIdentifier, DuperObject, DuperTemporal, DuperValue, visitor::DuperVisitor}; use toml::{Value, value::Datetime}; use crate::temporal::{Instant, PlainDate, PlainDateTime, PlainTime}; @@ -35,7 +32,7 @@ impl DuperVisitor for TomlVisitor { fn visit_array<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - array: &DuperArray<'a>, + array: &[DuperValue<'a>], ) -> Self::Value { let array: Result<_, _> = array .iter() @@ -47,7 +44,7 @@ impl DuperVisitor for TomlVisitor { fn visit_tuple<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - tuple: &DuperTuple<'a>, + tuple: &[DuperValue<'a>], ) -> Self::Value { let array: Result<_, _> = tuple .iter() @@ -59,54 +56,58 @@ impl DuperVisitor for TomlVisitor { fn visit_string<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - string: &DuperString<'a>, + string: &'a str, ) -> Self::Value { - Ok(Some(Value::String(string.as_ref().to_string()))) + Ok(Some(Value::String(string.to_string()))) } fn visit_bytes<'a>( &mut self, _identifier: Option<&DuperIdentifier<'a>>, - bytes: &DuperBytes<'a>, + bytes: &'a [u8], ) -> Self::Value { - Ok(Some(Value::String(BASE64_STANDARD.encode(bytes.as_ref())))) + Ok(Some(Value::String(BASE64_STANDARD.encode(bytes)))) } - fn visit_temporal<'a>( - &mut self, - _identifier: Option<&DuperIdentifier<'a>>, - temporal: &DuperTemporal<'a>, - ) -> Self::Value { + fn visit_temporal<'a>(&mut self, temporal: &DuperTemporal<'a>) -> Self::Value { match temporal { - DuperTemporal::Instant(inner) => { + DuperTemporal::Instant { inner } => { let datetime_str = Instant::from(inner.as_ref()).to_string(); Ok(Some(Value::Datetime( Datetime::from_str(&datetime_str).map_err(|err| err.to_string())?, ))) } - DuperTemporal::PlainDateTime(inner) => { + DuperTemporal::PlainDateTime { inner } => { let datetime_str = PlainDateTime::from(inner.as_ref()).to_string(); Ok(Some(Value::Datetime( Datetime::from_str(&datetime_str).map_err(|err| err.to_string())?, ))) } - DuperTemporal::PlainDate(inner) => { + DuperTemporal::PlainDate { inner } => { let datetime_str = PlainDate::from(inner.as_ref()).to_string(); Ok(Some(Value::Datetime( Datetime::from_str(&datetime_str).map_err(|err| err.to_string())?, ))) } - DuperTemporal::PlainTime(inner) => { + DuperTemporal::PlainTime { inner } => { let datetime_str = PlainTime::from(inner.as_ref()).to_string(); Ok(Some(Value::Datetime( Datetime::from_str(&datetime_str).map_err(|err| err.to_string())?, ))) } - DuperTemporal::ZonedDateTime(inner) - | DuperTemporal::PlainYearMonth(inner) - | DuperTemporal::PlainMonthDay(inner) - | DuperTemporal::Duration(inner) - | DuperTemporal::Unspecified(inner) => { + DuperTemporal::ZonedDateTime { inner } => { + Ok(Some(Value::String(inner.as_ref().to_string()))) + } + DuperTemporal::PlainYearMonth { inner } => { + Ok(Some(Value::String(inner.as_ref().to_string()))) + } + DuperTemporal::PlainMonthDay { inner } => { + Ok(Some(Value::String(inner.as_ref().to_string()))) + } + DuperTemporal::Duration { inner } => { + Ok(Some(Value::String(inner.as_ref().to_string()))) + } + DuperTemporal::Unspecified { inner, .. } => { Ok(Some(Value::String(inner.as_ref().to_string()))) } } diff --git a/duperq/src/accessor.rs b/duperq/src/accessor.rs index efb41ec..c729c6d 100644 --- a/duperq/src/accessor.rs +++ b/duperq/src/accessor.rs @@ -1,6 +1,6 @@ use std::{iter, ops::Bound}; -use duper::{DuperInner, DuperValue}; +use duper::{DuperKey, DuperValue}; use crate::filter::DuperFilter; @@ -42,34 +42,23 @@ impl DuperAccessor for SelfAccessor { } } -pub(crate) struct FieldAccessor(pub(crate) String); +pub(crate) struct FieldAccessor(pub(crate) DuperKey<'static>); impl DuperAccessor for FieldAccessor { fn access<'accessor: 'value, 'value>( &'accessor self, value: &'value DuperValue<'value>, ) -> AccessorReturn<'value> { - if let DuperInner::Object(object) = &value.inner { - Box::new( - object - .iter() - .find(|(key, _)| key.as_ref() == self.0) - .into_iter() - .map(|(_, value)| value), - ) - } else if let DuperInner::Array(array) = &value.inner { - Box::new(array.iter().filter_map(|duper| { - if let DuperInner::Object(object) = &duper.inner { - object - .iter() - .find(|(key, _)| key.as_ref() == self.0) - .map(|(_, value)| value) + match value { + DuperValue::Object { inner: object, .. } => Box::new(object.get(&self.0).into_iter()), + DuperValue::Array { inner: array, .. } => Box::new(array.iter().flat_map(|duper| { + if let DuperValue::Object { inner: object, .. } = &duper { + object.get(&self.0) } else { None } - })) - } else { - Box::new(iter::empty()) + })), + _ => Box::new(iter::empty()), } } } @@ -81,12 +70,10 @@ impl DuperAccessor for IndexAccessor { &'accessor self, value: &'value DuperValue<'value>, ) -> AccessorReturn<'value> { - if let DuperInner::Array(array) = &value.inner { - Box::new(array.get(self.0).into_iter()) - } else if let DuperInner::Tuple(tuple) = &value.inner { - Box::new(tuple.get(self.0).into_iter()) - } else { - Box::new(iter::empty()) + match value { + DuperValue::Array { inner: array, .. } => Box::new(array.get(self.0).into_iter()), + DuperValue::Tuple { inner: tuple, .. } => Box::new(tuple.get(self.0).into_iter()), + _ => Box::new(iter::empty()), } } } @@ -98,20 +85,22 @@ impl DuperAccessor for ReverseIndexAccessor { &'accessor self, value: &'value DuperValue<'value>, ) -> AccessorReturn<'value> { - if let DuperInner::Array(array) = &value.inner { - if let Some(index) = array.len().checked_sub(self.0) { - Box::new(array.get(index).into_iter()) - } else { - Box::new(iter::empty()) + match value { + DuperValue::Array { inner: array, .. } => { + if let Some(index) = array.len().checked_sub(self.0) { + Box::new(array.get(index).into_iter()) + } else { + Box::new(iter::empty()) + } } - } else if let DuperInner::Tuple(tuple) = &value.inner { - if let Some(index) = tuple.len().checked_sub(self.0) { - Box::new(tuple.get(index).into_iter()) - } else { - Box::new(iter::empty()) + DuperValue::Tuple { inner: tuple, .. } => { + if let Some(index) = tuple.len().checked_sub(self.0) { + Box::new(tuple.get(index).into_iter()) + } else { + Box::new(iter::empty()) + } } - } else { - Box::new(iter::empty()) + _ => Box::new(iter::empty()), } } } @@ -126,7 +115,7 @@ impl DuperAccessor for RangeIndexAccessor { &'accessor self, value: &'value DuperValue<'value>, ) -> AccessorReturn<'value> { - if let DuperInner::Array(array) = &value.inner { + if let DuperValue::Array { inner: array, .. } = value { let start = match self.start { Bound::Included(i) => i, Bound::Excluded(i) => i + 1, @@ -150,7 +139,7 @@ impl DuperAccessor for AnyAccessor { &'accessor self, value: &'value DuperValue<'value>, ) -> AccessorReturn<'value> { - if let DuperInner::Array(array) = &value.inner { + if let DuperValue::Array { inner: array, .. } = value { Box::new(array.iter()) } else { Box::new(iter::empty()) @@ -165,7 +154,7 @@ impl DuperAccessor for FilterAccessor { &'accessor self, value: &'value DuperValue<'value>, ) -> AccessorReturn<'value> { - if let DuperInner::Array(array) = &value.inner { + if let DuperValue::Array { inner: array, .. } = value { Box::new(array.iter().filter(|value| self.0.filter(value))) } else { Box::new(iter::empty()) diff --git a/duperq/src/filter.rs b/duperq/src/filter.rs index 73a3a77..cf1d66c 100644 --- a/duperq/src/filter.rs +++ b/duperq/src/filter.rs @@ -1,6 +1,6 @@ use std::{cmp::Ordering, fmt::Display, str::FromStr}; -use duper::{DuperInner, DuperValue}; +use duper::{DuperTemporal, DuperValue}; use temporal_rs::{ Duration, Instant, PlainDate, PlainDateTime, PlainMonthDay, PlainTime, PlainYearMonth, TemporalError, ZonedDateTime, @@ -158,54 +158,55 @@ impl EqValue { value: DuperValue<'_>, epsilon: Option, ) -> Result { - match value.inner { - DuperInner::Object(_) => Err(TryFromDuperValueError::InvalidType("Object")), - DuperInner::Array(_) => Err(TryFromDuperValueError::InvalidType("Array")), - DuperInner::Tuple(tuple) => { + match value { + DuperValue::Object { .. } => Err(TryFromDuperValueError::InvalidType("Object")), + DuperValue::Array { .. } => Err(TryFromDuperValueError::InvalidType("Array")), + DuperValue::Tuple { inner: tuple, .. } => { let vec: Result, _> = tuple - .into_inner() .into_iter() .map(|value| EqValue::try_from_duper(value, epsilon).map(EqFilter)) .collect(); Ok(EqValue::Tuple(vec?)) } - DuperInner::String(string) => Ok(EqValue::String(string.into_inner().into_owned())), - DuperInner::Bytes(bytes) => Ok(EqValue::Bytes(bytes.into_inner().into_owned())), - DuperInner::Temporal(temporal) => match value.identifier { - Some(identifier) if identifier.as_ref() == "Instant" => Ok( - EqValue::TemporalInstant(Instant::from_str(temporal.as_ref())?), - ), - Some(identifier) if identifier.as_ref() == "ZonedDateTime" => { + DuperValue::String { inner: string, .. } => Ok(EqValue::String(string.into_owned())), + DuperValue::Bytes { inner: bytes, .. } => Ok(EqValue::Bytes(bytes.into_owned())), + DuperValue::Temporal(temporal) => match temporal { + DuperTemporal::Instant { inner: temporal } => Ok(EqValue::TemporalInstant( + Instant::from_str(temporal.as_ref())?, + )), + DuperTemporal::ZonedDateTime { inner: temporal } => { Ok(EqValue::TemporalZonedDateTime(ZonedDateTime::from_utf8( temporal.as_ref().as_bytes(), Disambiguation::Compatible, OffsetDisambiguation::Prefer, )?)) } - Some(identifier) if identifier.as_ref() == "PlainDate" => Ok( - EqValue::TemporalPlainDate(PlainDate::from_str(temporal.as_ref())?), - ), - Some(identifier) if identifier.as_ref() == "PlainTime" => Ok( - EqValue::TemporalPlainTime(PlainTime::from_str(temporal.as_ref())?), - ), - Some(identifier) if identifier.as_ref() == "PlainDateTime" => Ok( + DuperTemporal::PlainDate { inner: temporal } => Ok(EqValue::TemporalPlainDate( + PlainDate::from_str(temporal.as_ref())?, + )), + DuperTemporal::PlainTime { inner: temporal } => Ok(EqValue::TemporalPlainTime( + PlainTime::from_str(temporal.as_ref())?, + )), + DuperTemporal::PlainDateTime { inner: temporal } => Ok( EqValue::TemporalPlainDateTime(PlainDateTime::from_str(temporal.as_ref())?), ), - Some(identifier) if identifier.as_ref() == "PlainYearMonth" => Ok( + DuperTemporal::PlainYearMonth { inner: temporal } => Ok( EqValue::TemporalPlainYearMonth(PlainYearMonth::from_str(temporal.as_ref())?), ), - Some(identifier) if identifier.as_ref() == "PlainMonthDay" => Ok( + DuperTemporal::PlainMonthDay { inner: temporal } => Ok( EqValue::TemporalPlainMonthDay(PlainMonthDay::from_str(temporal.as_ref())?), ), - Some(identifier) if identifier.as_ref() == "Duration" => Ok( - EqValue::TemporalDuration(Duration::from_str(temporal.as_ref())?), - ), - Some(_) | None => Err(TryFromDuperValueError::UnspecifiedTemporal), + DuperTemporal::Duration { inner: temporal } => Ok(EqValue::TemporalDuration( + Duration::from_str(temporal.as_ref())?, + )), + DuperTemporal::Unspecified { .. } => { + Err(TryFromDuperValueError::UnspecifiedTemporal) + } }, - DuperInner::Integer(integer) => Ok(EqValue::Integer(integer)), - DuperInner::Float(float) => Ok(EqValue::Float(float, epsilon)), - DuperInner::Boolean(boolean) => Ok(EqValue::Boolean(boolean)), - DuperInner::Null => Ok(EqValue::Null), + DuperValue::Integer { inner: integer, .. } => Ok(EqValue::Integer(integer)), + DuperValue::Float { inner: float, .. } => Ok(EqValue::Float(float, epsilon)), + DuperValue::Boolean { inner: boolean, .. } => Ok(EqValue::Boolean(boolean)), + DuperValue::Null { .. } => Ok(EqValue::Null), } } } @@ -214,20 +215,24 @@ pub(crate) struct EqFilter(pub(crate) EqValue); impl DuperFilter for EqFilter { fn filter<'v>(&self, value: &DuperValue<'v>) -> bool { - match (&self.0, &value.inner) { + match (&self.0, value) { (EqValue::Identifier(this), _) => match this { Some(this) => value - .identifier + .identifier() .as_ref() .is_some_and(|that| this == that.as_ref()), - None => value.identifier.is_none(), + None => value.identifier().is_none(), }, - (EqValue::Len(this), DuperInner::Object(that)) => *this == that.len(), - (EqValue::Len(this), DuperInner::Array(that)) => *this == that.len(), - (EqValue::Len(this), DuperInner::Tuple(that)) => *this == that.len(), - (EqValue::Len(this), DuperInner::String(that)) => *this == that.as_ref().len(), - (EqValue::Len(this), DuperInner::Bytes(that)) => *this == that.as_ref().len(), - (EqValue::Tuple(this), DuperInner::Tuple(that)) => { + (EqValue::Len(this), DuperValue::Object { inner: that, .. }) => *this == that.len(), + (EqValue::Len(this), DuperValue::Array { inner: that, .. }) => *this == that.len(), + (EqValue::Len(this), DuperValue::Tuple { inner: that, .. }) => *this == that.len(), + (EqValue::Len(this), DuperValue::String { inner: that, .. }) => { + *this == that.as_ref().len() + } + (EqValue::Len(this), DuperValue::Bytes { inner: that, .. }) => { + *this == that.as_ref().len() + } + (EqValue::Tuple(this), DuperValue::Tuple { inner: that, .. }) => { if this.len() == that.len() { this.iter() .zip(that.iter()) @@ -236,12 +241,14 @@ impl DuperFilter for EqFilter { false } } - (EqValue::String(this), DuperInner::String(that)) => this == that.as_ref(), - (EqValue::Bytes(this), DuperInner::Bytes(that)) => this == that.as_ref(), - (EqValue::TemporalInstant(this), DuperInner::Temporal(that)) => { + (EqValue::String(this), DuperValue::String { inner: that, .. }) => { + this == that.as_ref() + } + (EqValue::Bytes(this), DuperValue::Bytes { inner: that, .. }) => this == that.as_ref(), + (EqValue::TemporalInstant(this), DuperValue::Temporal(that)) => { Instant::from_str(that.as_ref()).is_ok_and(|that| *this == that) } - (EqValue::TemporalZonedDateTime(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalZonedDateTime(this), DuperValue::Temporal(that)) => { ZonedDateTime::from_utf8( that.as_ref().as_bytes(), Disambiguation::Compatible, @@ -249,34 +256,36 @@ impl DuperFilter for EqFilter { ) .is_ok_and(|that| this.compare_instant(&that).is_eq()) } - (EqValue::TemporalPlainDate(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainDate(this), DuperValue::Temporal(that)) => { PlainDate::from_str(that.as_ref()).is_ok_and(|that| *this == that) } - (EqValue::TemporalPlainTime(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainTime(this), DuperValue::Temporal(that)) => { PlainTime::from_str(that.as_ref()).is_ok_and(|that| *this == that) } - (EqValue::TemporalPlainDateTime(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainDateTime(this), DuperValue::Temporal(that)) => { PlainDateTime::from_str(that.as_ref()).is_ok_and(|that| *this == that) } - (EqValue::TemporalPlainYearMonth(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainYearMonth(this), DuperValue::Temporal(that)) => { PlainYearMonth::from_str(that.as_ref()).is_ok_and(|that| *this == that) } - (EqValue::TemporalPlainMonthDay(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainMonthDay(this), DuperValue::Temporal(that)) => { PlainMonthDay::from_str(that.as_ref()).is_ok_and(|that| *this == that) } - (EqValue::TemporalDuration(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalDuration(this), DuperValue::Temporal(that)) => { Duration::from_str(that.as_ref()).is_ok_and(|that| *this == that) } - (EqValue::Integer(this), DuperInner::Integer(that)) => this == that, - (EqValue::Float(this, epsilon), DuperInner::Float(that)) => { + (EqValue::Integer(this), DuperValue::Integer { inner: that, .. }) => this == that, + (EqValue::Float(this, epsilon), DuperValue::Float { inner: that, .. }) => { (this - that).abs() <= epsilon.unwrap_or(0.0).abs() } - (EqValue::Integer(this), DuperInner::Float(that)) => *this == *that as i64, - (EqValue::Float(this, epsilon), DuperInner::Integer(that)) => { + (EqValue::Integer(this), DuperValue::Float { inner: that, .. }) => { + *this == *that as i64 + } + (EqValue::Float(this, epsilon), DuperValue::Integer { inner: that, .. }) => { (this - *that as f64).abs() <= epsilon.unwrap_or(0.0).abs() } - (EqValue::Boolean(this), DuperInner::Boolean(that)) => this == that, - (EqValue::Null, DuperInner::Null) => true, + (EqValue::Boolean(this), DuperValue::Boolean { inner: that, .. }) => this == that, + (EqValue::Null, DuperValue::Null { .. }) => true, _ => false, } } @@ -286,19 +295,23 @@ pub(crate) struct NeFilter(pub(crate) EqValue); impl DuperFilter for NeFilter { fn filter<'v>(&self, value: &DuperValue<'v>) -> bool { - match (&self.0, &value.inner) { + match (&self.0, value) { (EqValue::Identifier(this), _) => match this { Some(this) => value - .identifier + .identifier() .as_ref() .is_none_or(|that| this != that.as_ref()), - None => value.identifier.is_some(), + None => value.identifier().is_some(), }, - (EqValue::Len(this), DuperInner::Object(that)) => *this != that.len(), - (EqValue::Len(this), DuperInner::Array(that)) => *this != that.len(), - (EqValue::Len(this), DuperInner::String(that)) => *this != that.as_ref().len(), - (EqValue::Len(this), DuperInner::Bytes(that)) => *this != that.as_ref().len(), - (EqValue::Tuple(this), DuperInner::Tuple(that)) => { + (EqValue::Len(this), DuperValue::Object { inner: that, .. }) => *this != that.len(), + (EqValue::Len(this), DuperValue::Array { inner: that, .. }) => *this != that.len(), + (EqValue::Len(this), DuperValue::String { inner: that, .. }) => { + *this != that.as_ref().len() + } + (EqValue::Len(this), DuperValue::Bytes { inner: that, .. }) => { + *this != that.as_ref().len() + } + (EqValue::Tuple(this), DuperValue::Tuple { inner: that, .. }) => { if this.len() == that.len() { this.iter() .zip(that.iter()) @@ -307,14 +320,16 @@ impl DuperFilter for NeFilter { true } } - (EqValue::String(this), DuperInner::String(that)) => this != that.as_ref(), - (EqValue::Bytes(this), DuperInner::Bytes(that)) => this != that.as_ref(), - (EqValue::TemporalInstant(this), DuperInner::Temporal(that)) => { + (EqValue::String(this), DuperValue::String { inner: that, .. }) => { + this != that.as_ref() + } + (EqValue::Bytes(this), DuperValue::Bytes { inner: that, .. }) => this != that.as_ref(), + (EqValue::TemporalInstant(this), DuperValue::Temporal(that)) => { Instant::from_str(that.as_ref()) .ok() .is_none_or(|that| *this != that) } - (EqValue::TemporalZonedDateTime(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalZonedDateTime(this), DuperValue::Temporal(that)) => { ZonedDateTime::from_utf8( that.as_ref().as_bytes(), Disambiguation::Compatible, @@ -323,46 +338,48 @@ impl DuperFilter for NeFilter { .ok() .is_none_or(|that| this.compare_instant(&that).is_ne()) } - (EqValue::TemporalPlainDate(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainDate(this), DuperValue::Temporal(that)) => { PlainDate::from_str(that.as_ref()) .ok() .is_none_or(|that| *this != that) } - (EqValue::TemporalPlainTime(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainTime(this), DuperValue::Temporal(that)) => { PlainTime::from_str(that.as_ref()) .ok() .is_none_or(|that| *this != that) } - (EqValue::TemporalPlainDateTime(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainDateTime(this), DuperValue::Temporal(that)) => { PlainDateTime::from_str(that.as_ref()) .ok() .is_none_or(|that| *this != that) } - (EqValue::TemporalPlainYearMonth(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainYearMonth(this), DuperValue::Temporal(that)) => { PlainYearMonth::from_str(that.as_ref()) .ok() .is_none_or(|that| *this != that) } - (EqValue::TemporalPlainMonthDay(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalPlainMonthDay(this), DuperValue::Temporal(that)) => { PlainMonthDay::from_str(that.as_ref()) .ok() .is_none_or(|that| *this != that) } - (EqValue::TemporalDuration(this), DuperInner::Temporal(that)) => { + (EqValue::TemporalDuration(this), DuperValue::Temporal(that)) => { Duration::from_str(that.as_ref()) .ok() .is_none_or(|that| *this != that) } - (EqValue::Integer(this), DuperInner::Integer(that)) => this != that, - (EqValue::Float(this, epsilon), DuperInner::Float(that)) => { + (EqValue::Integer(this), DuperValue::Integer { inner: that, .. }) => this != that, + (EqValue::Float(this, epsilon), DuperValue::Float { inner: that, .. }) => { (this - that).abs() > epsilon.unwrap_or(0.0).abs() } - (EqValue::Integer(this), DuperInner::Float(that)) => *this != *that as i64, - (EqValue::Float(this, epsilon), DuperInner::Integer(that)) => { + (EqValue::Integer(this), DuperValue::Float { inner: that, .. }) => { + *this != *that as i64 + } + (EqValue::Float(this, epsilon), DuperValue::Integer { inner: that, .. }) => { (this - *that as f64).abs() > epsilon.unwrap_or(0.0).abs() } - (EqValue::Boolean(this), DuperInner::Boolean(that)) => this != that, - (EqValue::Null, DuperInner::Null) => false, + (EqValue::Boolean(this), DuperValue::Boolean { inner: that, .. }) => this != that, + (EqValue::Null, DuperValue::Null { .. }) => false, _ => true, } } @@ -385,47 +402,49 @@ impl TryFrom> for CmpValue { type Error = TryFromDuperValueError; fn try_from(value: DuperValue<'_>) -> Result { - match value.inner { - DuperInner::Object(_) => Err(TryFromDuperValueError::InvalidType("Object")), - DuperInner::Array(_) => Err(TryFromDuperValueError::InvalidType("Array")), - DuperInner::Tuple(_) => Err(TryFromDuperValueError::InvalidType("Tuple")), - DuperInner::String(_) => Err(TryFromDuperValueError::InvalidType("String")), - DuperInner::Bytes(_) => Err(TryFromDuperValueError::InvalidType("Bytes")), - DuperInner::Temporal(temporal) => match value.identifier { - Some(identifier) if identifier.as_ref() == "Instant" => Ok( - CmpValue::TemporalInstant(Instant::from_str(temporal.as_ref())?), - ), - Some(identifier) if identifier.as_ref() == "ZonedDateTime" => { + match value { + DuperValue::Object { .. } => Err(TryFromDuperValueError::InvalidType("Object")), + DuperValue::Array { .. } => Err(TryFromDuperValueError::InvalidType("Array")), + DuperValue::Tuple { .. } => Err(TryFromDuperValueError::InvalidType("Tuple")), + DuperValue::String { .. } => Err(TryFromDuperValueError::InvalidType("String")), + DuperValue::Bytes { .. } => Err(TryFromDuperValueError::InvalidType("Bytes")), + DuperValue::Temporal(temporal) => match temporal { + DuperTemporal::Instant { inner: temporal } => Ok(CmpValue::TemporalInstant( + Instant::from_str(temporal.as_ref())?, + )), + DuperTemporal::ZonedDateTime { inner: temporal } => { Ok(CmpValue::TemporalZonedDateTime(ZonedDateTime::from_utf8( temporal.as_ref().as_bytes(), Disambiguation::Compatible, OffsetDisambiguation::Prefer, )?)) } - Some(identifier) if identifier.as_ref() == "PlainDate" => Ok( - CmpValue::TemporalPlainDate(PlainDate::from_str(temporal.as_ref())?), - ), - Some(identifier) if identifier.as_ref() == "PlainTime" => Ok( - CmpValue::TemporalPlainTime(PlainTime::from_str(temporal.as_ref())?), - ), - Some(identifier) if identifier.as_ref() == "PlainDateTime" => Ok( + DuperTemporal::PlainDate { inner: temporal } => Ok(CmpValue::TemporalPlainDate( + PlainDate::from_str(temporal.as_ref())?, + )), + DuperTemporal::PlainTime { inner: temporal } => Ok(CmpValue::TemporalPlainTime( + PlainTime::from_str(temporal.as_ref())?, + )), + DuperTemporal::PlainDateTime { inner: temporal } => Ok( CmpValue::TemporalPlainDateTime(PlainDateTime::from_str(temporal.as_ref())?), ), - Some(identifier) if identifier.as_ref() == "PlainYearMonth" => Ok( + DuperTemporal::PlainYearMonth { inner: temporal } => Ok( CmpValue::TemporalPlainYearMonth(PlainYearMonth::from_str(temporal.as_ref())?), ), - Some(identifier) if identifier.as_ref() == "PlainMonthDay" => { + DuperTemporal::PlainMonthDay { .. } => { Err(TryFromDuperValueError::InvalidType("PlainMonthDay")) } - Some(identifier) if identifier.as_ref() == "Duration" => Ok( - CmpValue::TemporalDuration(Duration::from_str(temporal.as_ref())?), - ), - Some(_) | None => Err(TryFromDuperValueError::UnspecifiedTemporal), + DuperTemporal::Duration { inner: temporal } => Ok(CmpValue::TemporalDuration( + Duration::from_str(temporal.as_ref())?, + )), + DuperTemporal::Unspecified { .. } => { + Err(TryFromDuperValueError::UnspecifiedTemporal) + } }, - DuperInner::Integer(integer) => Ok(CmpValue::Integer(integer)), - DuperInner::Float(float) => Ok(CmpValue::Float(float)), - DuperInner::Boolean(_) => Err(TryFromDuperValueError::InvalidType("Boolean")), - DuperInner::Null => Err(TryFromDuperValueError::InvalidType("Null")), + DuperValue::Integer { inner: integer, .. } => Ok(CmpValue::Integer(integer)), + DuperValue::Float { inner: float, .. } => Ok(CmpValue::Float(float)), + DuperValue::Boolean { .. } => Err(TryFromDuperValueError::InvalidType("Boolean")), + DuperValue::Null { .. } => Err(TryFromDuperValueError::InvalidType("Null")), } } } @@ -439,24 +458,24 @@ macro_rules! cmp_filter { impl DuperFilter for $filter { fn filter<'v>(&self, value: &DuperValue<'v>) -> bool { - match (&self.0, &value.inner) { - (CmpValue::Len(this), DuperInner::Object(that)) => { + match (&self.0, value) { + (CmpValue::Len(this), DuperValue::Object { inner: that, .. }) => { matches!(that.len().cmp(this), $ord) } - (CmpValue::Len(this), DuperInner::Array(that)) => { + (CmpValue::Len(this), DuperValue::Array { inner: that, .. }) => { matches!(that.len().cmp(this), $ord) } - (CmpValue::Len(this), DuperInner::String(that)) => { + (CmpValue::Len(this), DuperValue::String { inner: that, .. }) => { matches!(that.as_ref().len().cmp(this), $ord) } - (CmpValue::Len(this), DuperInner::Bytes(that)) => { + (CmpValue::Len(this), DuperValue::Bytes { inner: that, .. }) => { matches!(that.as_ref().len().cmp(this), $ord) } - (CmpValue::TemporalInstant(this), DuperInner::Temporal(that)) => { + (CmpValue::TemporalInstant(this), DuperValue::Temporal(that)) => { Instant::from_str(that.as_ref()) .is_ok_and(|that| matches!(that.cmp(this), $ord)) } - (CmpValue::TemporalZonedDateTime(this), DuperInner::Temporal(that)) => { + (CmpValue::TemporalZonedDateTime(this), DuperValue::Temporal(that)) => { ZonedDateTime::from_utf8( that.as_ref().as_bytes(), Disambiguation::Compatible, @@ -464,36 +483,36 @@ macro_rules! cmp_filter { ) .is_ok_and(|that| matches!(that.compare_instant(this), $ord)) } - (CmpValue::TemporalPlainDate(this), DuperInner::Temporal(that)) => { + (CmpValue::TemporalPlainDate(this), DuperValue::Temporal(that)) => { PlainDate::from_str(that.as_ref()) .is_ok_and(|that| matches!(that.compare_iso(this), $ord)) } - (CmpValue::TemporalPlainTime(this), DuperInner::Temporal(that)) => { + (CmpValue::TemporalPlainTime(this), DuperValue::Temporal(that)) => { PlainTime::from_str(that.as_ref()) .is_ok_and(|that| matches!(that.cmp(this), $ord)) } - (CmpValue::TemporalPlainDateTime(this), DuperInner::Temporal(that)) => { + (CmpValue::TemporalPlainDateTime(this), DuperValue::Temporal(that)) => { PlainDateTime::from_str(that.as_ref()) .is_ok_and(|that| matches!(that.compare_iso(this), $ord)) } - (CmpValue::TemporalPlainYearMonth(this), DuperInner::Temporal(that)) => { + (CmpValue::TemporalPlainYearMonth(this), DuperValue::Temporal(that)) => { PlainYearMonth::from_str(that.as_ref()) .is_ok_and(|that| matches!(that.compare_iso(this), $ord)) } - (CmpValue::TemporalDuration(this), DuperInner::Temporal(that)) => { + (CmpValue::TemporalDuration(this), DuperValue::Temporal(that)) => { Duration::from_str(that.as_ref()) .is_ok_and(|that| matches!(that.partial_cmp(this), Some($ord))) } - (CmpValue::Integer(this), DuperInner::Integer(that)) => { + (CmpValue::Integer(this), DuperValue::Integer { inner: that, .. }) => { matches!(that.cmp(this), $ord) } - (CmpValue::Float(this), DuperInner::Float(that)) => { + (CmpValue::Float(this), DuperValue::Float { inner: that, .. }) => { matches!(that.partial_cmp(this), Some($ord)) } - (CmpValue::Integer(this), DuperInner::Float(that)) => { + (CmpValue::Integer(this), DuperValue::Float { inner: that, .. }) => { matches!((*that as i64).cmp(this), $ord) } - (CmpValue::Float(this), DuperInner::Integer(that)) => { + (CmpValue::Float(this), DuperValue::Integer { inner: that, .. }) => { matches!((*that as f64).partial_cmp(this), Some($ord)) } _ => false, @@ -513,16 +532,16 @@ pub(crate) struct IsFilter(pub(crate) DuperType); impl DuperFilter for IsFilter { fn filter<'v>(&self, value: &DuperValue<'v>) -> bool { - match (&self.0, &value.inner) { - (DuperType::Object, DuperInner::Object(_)) => true, - (DuperType::Array, DuperInner::Array(_)) => true, - (DuperType::Tuple, DuperInner::Tuple(_)) => true, - (DuperType::String, DuperInner::String(_)) => true, - (DuperType::Bytes, DuperInner::Bytes(_)) => true, - (DuperType::TemporalInstant, DuperInner::Temporal(that)) => { + match (&self.0, value) { + (DuperType::Object, DuperValue::Object { .. }) => true, + (DuperType::Array, DuperValue::Array { .. }) => true, + (DuperType::Tuple, DuperValue::Tuple { .. }) => true, + (DuperType::String, DuperValue::String { .. }) => true, + (DuperType::Bytes, DuperValue::Bytes { .. }) => true, + (DuperType::TemporalInstant, DuperValue::Temporal(that)) => { Instant::from_str(that.as_ref()).is_ok() } - (DuperType::TemporalZonedDateTime, DuperInner::Temporal(that)) => { + (DuperType::TemporalZonedDateTime, DuperValue::Temporal(that)) => { ZonedDateTime::from_utf8( that.as_ref().as_bytes(), Disambiguation::Compatible, @@ -530,30 +549,30 @@ impl DuperFilter for IsFilter { ) .is_ok() } - (DuperType::TemporalPlainDate, DuperInner::Temporal(that)) => { + (DuperType::TemporalPlainDate, DuperValue::Temporal(that)) => { PlainDate::from_str(that.as_ref()).is_ok() } - (DuperType::TemporalPlainTime, DuperInner::Temporal(that)) => { + (DuperType::TemporalPlainTime, DuperValue::Temporal(that)) => { PlainTime::from_str(that.as_ref()).is_ok() } - (DuperType::TemporalPlainDateTime, DuperInner::Temporal(that)) => { + (DuperType::TemporalPlainDateTime, DuperValue::Temporal(that)) => { PlainDateTime::from_str(that.as_ref()).is_ok() } - (DuperType::TemporalPlainYearMonth, DuperInner::Temporal(that)) => { + (DuperType::TemporalPlainYearMonth, DuperValue::Temporal(that)) => { PlainYearMonth::from_str(that.as_ref()).is_ok() } - (DuperType::TemporalPlainMonthDay, DuperInner::Temporal(that)) => { + (DuperType::TemporalPlainMonthDay, DuperValue::Temporal(that)) => { PlainMonthDay::from_str(that.as_ref()).is_ok() } - (DuperType::TemporalDuration, DuperInner::Temporal(that)) => { + (DuperType::TemporalDuration, DuperValue::Temporal(that)) => { Duration::from_str(that.as_ref()).is_ok() } - (DuperType::TemporalUnspecified, DuperInner::Temporal(_)) => true, - (DuperType::Integer, DuperInner::Integer(_)) => true, - (DuperType::Float, DuperInner::Float(_)) => true, - (DuperType::Number, DuperInner::Integer(_) | DuperInner::Float(_)) => true, - (DuperType::Boolean, DuperInner::Boolean(_)) => true, - (DuperType::Null, DuperInner::Null) => true, + (DuperType::TemporalUnspecified, DuperValue::Temporal { .. }) => true, + (DuperType::Integer, DuperValue::Integer { .. }) => true, + (DuperType::Float, DuperValue::Float { .. }) => true, + (DuperType::Number, DuperValue::Integer { .. } | DuperValue::Float { .. }) => true, + (DuperType::Boolean, DuperValue::Boolean { .. }) => true, + (DuperType::Null, DuperValue::Null { .. }) => true, _ => false, } } @@ -563,10 +582,12 @@ pub(crate) struct RegexFilter(pub(crate) regex::bytes::Regex); impl DuperFilter for RegexFilter { fn filter<'v>(&self, value: &DuperValue<'v>) -> bool { - match &value.inner { - DuperInner::String(string) => self.0.find(string.as_ref().as_bytes()).is_some(), - DuperInner::Bytes(bytes) => self.0.find(bytes.as_ref()).is_some(), - DuperInner::Temporal(temporal) => self.0.find(temporal.as_ref().as_bytes()).is_some(), + match value { + DuperValue::String { inner: string, .. } => { + self.0.find(string.as_ref().as_bytes()).is_some() + } + DuperValue::Bytes { inner: bytes, .. } => self.0.find(bytes.as_ref()).is_some(), + DuperValue::Temporal(temporal) => self.0.find(temporal.as_ref().as_bytes()).is_some(), _ => false, } } @@ -577,7 +598,7 @@ pub(crate) struct RegexIdentifierFilter(pub(crate) regex::Regex); impl DuperFilter for RegexIdentifierFilter { fn filter<'v>(&self, value: &DuperValue<'v>) -> bool { value - .identifier + .identifier() .as_ref() .is_some_and(|identifier| self.0.find(identifier.as_ref()).is_some()) } @@ -587,17 +608,17 @@ pub(crate) struct IsTruthyFilter; impl DuperFilter for IsTruthyFilter { fn filter<'v>(&self, value: &DuperValue<'_>) -> bool { - match &value.inner { - DuperInner::Object(object) => !object.is_empty(), - DuperInner::Array(array) => !array.is_empty(), - DuperInner::Tuple(tuple) => !tuple.is_empty(), - DuperInner::String(string) => !string.is_empty(), - DuperInner::Bytes(bytes) => !bytes.is_empty(), - DuperInner::Temporal(_) => true, - DuperInner::Integer(integer) => *integer != 0, - DuperInner::Float(float) => *float != 0.0, - DuperInner::Boolean(boolean) => *boolean, - DuperInner::Null => false, + match value { + DuperValue::Object { inner: object, .. } => !object.is_empty(), + DuperValue::Array { inner: array, .. } => !array.is_empty(), + DuperValue::Tuple { inner: tuple, .. } => !tuple.is_empty(), + DuperValue::String { inner: string, .. } => !string.is_empty(), + DuperValue::Bytes { inner: bytes, .. } => !bytes.is_empty(), + DuperValue::Temporal { .. } => true, + DuperValue::Integer { inner: integer, .. } => *integer != 0, + DuperValue::Float { inner: float, .. } => *float != 0.0, + DuperValue::Boolean { inner: boolean, .. } => *boolean, + DuperValue::Null { .. } => false, } } } diff --git a/duperq/src/formatter.rs b/duperq/src/formatter.rs index a25b36c..fb2ffa3 100644 --- a/duperq/src/formatter.rs +++ b/duperq/src/formatter.rs @@ -1,8 +1,7 @@ // duperq 'span.tagged && span[0]name == sp0001 | "[${level}] ${span[0]time} - ${span[0]status} ${telemetry.duration:ms}"' use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperObject, DuperString, DuperTemporal, DuperTuple, - DuperValue, + DuperIdentifier, DuperObject, DuperTemporal, DuperValue, format::{ format_boolean, format_duper_bytes, format_duper_string, format_float, format_integer, format_key, format_null, format_temporal, @@ -114,7 +113,7 @@ impl DuperVisitor for FormatterVisitor { fn visit_array<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - array: &DuperArray<'a>, + array: &[DuperValue<'a>], ) -> Self::Value { let len = array.len(); @@ -143,7 +142,7 @@ impl DuperVisitor for FormatterVisitor { fn visit_tuple<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - tuple: &DuperTuple<'a>, + tuple: &[DuperValue<'a>], ) -> Self::Value { let len = tuple.len(); @@ -172,7 +171,7 @@ impl DuperVisitor for FormatterVisitor { fn visit_string<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - value: &DuperString<'a>, + value: &'a str, ) -> Self::Value { if let Some(identifier) = identifier { let value = format_duper_string(value); @@ -185,7 +184,7 @@ impl DuperVisitor for FormatterVisitor { fn visit_bytes<'a>( &mut self, identifier: Option<&DuperIdentifier<'a>>, - bytes: &DuperBytes<'a>, + bytes: &'a [u8], ) -> Self::Value { if let Some(identifier) = identifier { let bytes = format_duper_bytes(bytes); @@ -195,11 +194,8 @@ impl DuperVisitor for FormatterVisitor { } } - fn visit_temporal<'a>( - &mut self, - identifier: Option<&DuperIdentifier<'a>>, - temporal: &DuperTemporal<'a>, - ) -> Self::Value { + fn visit_temporal<'a>(&mut self, temporal: &DuperTemporal<'a>) -> Self::Value { + let identifier = temporal.identifier(); if let Some(identifier) = identifier { let value = format_temporal(temporal); self.buf.push_str(&format!("{identifier}({value})")); diff --git a/duperq/src/query.rs b/duperq/src/query.rs index 80a9f38..9e8ac2f 100644 --- a/duperq/src/query.rs +++ b/duperq/src/query.rs @@ -1,6 +1,6 @@ use chumsky::prelude::*; use duper::{ - Ansi, DuperInner, DuperValue, PrettyPrinter, Serializer, + Ansi, DuperValue, PrettyPrinter, Serializer, escape::unescape_str, parser::{identified_value, integer, object_key, quoted_string}, }; @@ -143,7 +143,7 @@ fn accessor<'a>() recursive(|accessor| { let access = choice(( just('.').ignore_then(object_key().map(|key: duper::DuperKey<'a>| { - Box::new(FieldAccessor(key.as_ref().into())) as Box + Box::new(FieldAccessor(key.static_clone())) as Box })), just('.').map(|_| Box::new(SelfAccessor) as Box), integer() @@ -362,8 +362,8 @@ fn leaf_filter<'a>( }), re_op .ignore_then(identified_value().padded()) - .try_map(|value, span| match value.inner { - DuperInner::String(string) => regex::Regex::new(string.as_ref()) + .try_map(|value, span| match value { + DuperValue::String { inner: string, .. } => regex::Regex::new(string.as_ref()) .map(|regex| Box::new(RegexIdentifierFilter(regex)) as Box) .map_err(|error| Rich::custom(span, error)), _ => Err(Rich::custom( @@ -426,10 +426,12 @@ fn leaf_filter<'a>( }), re_op .ignore_then(identified_value().padded()) - .try_map(|value, span| match value.inner { - DuperInner::String(string) => regex::bytes::Regex::new(string.as_ref()) - .map(|regex| Box::new(RegexFilter(regex)) as Box) - .map_err(|error| Rich::custom(span, error)), + .try_map(|value, span| match value { + DuperValue::String { inner: string, .. } => { + regex::bytes::Regex::new(string.as_ref()) + .map(|regex| Box::new(RegexFilter(regex)) as Box) + .map_err(|error| Rich::custom(span, error)) + } _ => Err(Rich::custom( span, "can only use regex operator =~ with string", diff --git a/duperq/src/types.rs b/duperq/src/types.rs index 91ec8e3..5272d0e 100644 --- a/duperq/src/types.rs +++ b/duperq/src/types.rs @@ -1,9 +1,6 @@ use std::borrow::Cow; -use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperInner, DuperString, DuperTemporal, DuperTuple, - DuperValue, -}; +use duper::DuperValue; use crate::filter::{DuperFilter, IsTruthyFilter}; @@ -35,13 +32,14 @@ impl DuperType { &self, value: &'value DuperValue<'value>, ) -> Option> { - match (self, &value.inner) { + match (self, &value) { // Trivial casts - (DuperType::Object, DuperInner::Object(_)) => Some(value.clone()), - (DuperType::Array, DuperInner::Array(_)) => Some(value.clone()), - (DuperType::Tuple, DuperInner::Tuple(_)) => Some(value.clone()), - (DuperType::String, DuperInner::String(_)) => Some(value.clone()), - (DuperType::Bytes, DuperInner::Bytes(_)) => Some(value.clone()), + (DuperType::Object, DuperValue::Object { .. }) => Some(value.clone()), + (DuperType::Array, DuperValue::Array { .. }) => Some(value.clone()), + (DuperType::Tuple, DuperValue::Tuple { .. }) => Some(value.clone()), + (DuperType::String, DuperValue::String { .. }) => Some(value.clone()), + (DuperType::Bytes, DuperValue::Bytes { .. }) => Some(value.clone()), + // TO-DO: Validate this ( DuperType::TemporalInstant | DuperType::TemporalZonedDateTime @@ -52,265 +50,165 @@ impl DuperType { | DuperType::TemporalPlainMonthDay | DuperType::TemporalDuration | DuperType::TemporalUnspecified, - DuperInner::Temporal(_), + DuperValue::Temporal(_), ) => Some(value.clone()), - (DuperType::Integer, DuperInner::Integer(_)) => Some(value.clone()), - (DuperType::Float, DuperInner::Float(_)) => Some(value.clone()), - (DuperType::Number, DuperInner::Integer(_) | DuperInner::Float(_)) => { + (DuperType::Integer, DuperValue::Integer { .. }) => Some(value.clone()), + (DuperType::Float, DuperValue::Float { .. }) => Some(value.clone()), + (DuperType::Number, DuperValue::Integer { .. } | DuperValue::Float { .. }) => { Some(value.clone()) } - (DuperType::Boolean, DuperInner::Boolean(_)) => Some(value.clone()), - (DuperType::Null, DuperInner::Null) => Some(value.clone()), + (DuperType::Boolean, DuperValue::Boolean { .. }) => Some(value.clone()), + (DuperType::Null, DuperValue::Null { .. }) => Some(value.clone()), // Non-trivial casts - (DuperType::Array, DuperInner::Tuple(tuple)) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Array(DuperArray::from( - tuple.iter().cloned().collect::>(), - )), + ( + DuperType::Array, + DuperValue::Tuple { + inner: tuple, + identifier, + }, + ) => Some(DuperValue::Array { + identifier: identifier.clone(), + inner: tuple.iter().cloned().collect::>(), }), - (DuperType::Tuple, DuperInner::Array(array)) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Tuple(DuperTuple::from( - array.iter().cloned().collect::>(), - )), + ( + DuperType::Tuple, + DuperValue::Array { + inner: array, + identifier, + }, + ) => Some(DuperValue::Tuple { + identifier: identifier.clone(), + inner: array.iter().cloned().collect::>(), }), - (DuperType::String, DuperInner::Bytes(bytes)) => str::from_utf8(bytes.as_ref()) + ( + DuperType::String, + DuperValue::Bytes { + inner: bytes, + identifier, + }, + ) => str::from_utf8(bytes.as_ref()) .ok() - .map(|string| DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::String(DuperString::from(Cow::Borrowed(string))), + .map(|string| DuperValue::String { + identifier: identifier.clone(), + inner: Cow::Borrowed(string), }), - (DuperType::String, DuperInner::Temporal(temporal)) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::String(DuperString::from(Cow::Borrowed(temporal.as_ref()))), + (DuperType::String, DuperValue::Temporal(temporal)) => Some(DuperValue::String { + identifier: temporal.identifier().clone(), + inner: Cow::Borrowed(temporal.as_ref()), }), - (DuperType::Bytes, DuperInner::String(string)) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Bytes(DuperBytes::from(Cow::Borrowed( - string.as_ref().as_bytes(), - ))), + ( + DuperType::Bytes, + DuperValue::String { + inner: string, + identifier, + }, + ) => Some(DuperValue::Bytes { + identifier: identifier.clone(), + inner: Cow::Borrowed(string.as_ref().as_bytes()), }), - (DuperType::Bytes, DuperInner::Temporal(temporal)) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Bytes(DuperBytes::from(Cow::Borrowed( - temporal.as_ref().as_bytes(), - ))), + (DuperType::Bytes, DuperValue::Temporal(temporal)) => Some(DuperValue::Bytes { + identifier: temporal.identifier().clone(), + inner: Cow::Borrowed(temporal.as_ref().as_bytes()), }), - (DuperType::TemporalInstant, DuperInner::String(string)) => { - DuperTemporal::try_instant_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("Instant").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalInstant, DuperValue::String { inner: string, .. }) => { + DuperValue::try_instant_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalInstant, DuperInner::Bytes(bytes)) => { + (DuperType::TemporalInstant, DuperValue::Bytes { inner: bytes, .. }) => { str::from_utf8(bytes.as_ref()) .ok() - .and_then(|string| DuperTemporal::try_instant_from(Cow::Borrowed(string)).ok()) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("Instant").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + .and_then(|string| DuperValue::try_instant_from(Cow::Borrowed(string)).ok()) } - (DuperType::TemporalZonedDateTime, DuperInner::String(string)) => { - DuperTemporal::try_zoned_date_time_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("ZonedDateTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalZonedDateTime, DuperValue::String { inner: string, .. }) => { + DuperValue::try_zoned_date_time_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalZonedDateTime, DuperInner::Bytes(bytes)) => { - str::from_utf8(bytes.as_ref()) - .ok() - .and_then(|string| { - DuperTemporal::try_zoned_date_time_from(Cow::Borrowed(string)).ok() - }) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("ZonedDateTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalZonedDateTime, DuperValue::Bytes { inner: bytes, .. }) => { + str::from_utf8(bytes.as_ref()).ok().and_then(|string| { + DuperValue::try_zoned_date_time_from(Cow::Borrowed(string)).ok() + }) } - (DuperType::TemporalPlainDate, DuperInner::String(string)) => { - DuperTemporal::try_plain_date_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainDate").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainDate, DuperValue::String { inner: string, .. }) => { + DuperValue::try_plain_date_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalPlainDate, DuperInner::Bytes(bytes)) => { + (DuperType::TemporalPlainDate, DuperValue::Bytes { inner: bytes, .. }) => { str::from_utf8(bytes.as_ref()) .ok() - .and_then(|string| { - DuperTemporal::try_plain_date_from(Cow::Borrowed(string)).ok() - }) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainDate").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + .and_then(|string| DuperValue::try_plain_date_from(Cow::Borrowed(string)).ok()) } - (DuperType::TemporalPlainTime, DuperInner::String(string)) => { - DuperTemporal::try_plain_time_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainTime, DuperValue::String { inner: string, .. }) => { + DuperValue::try_plain_time_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalPlainTime, DuperInner::Bytes(bytes)) => { + (DuperType::TemporalPlainTime, DuperValue::Bytes { inner: bytes, .. }) => { str::from_utf8(bytes.as_ref()) .ok() - .and_then(|string| { - DuperTemporal::try_plain_time_from(Cow::Borrowed(string)).ok() - }) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + .and_then(|string| DuperValue::try_plain_time_from(Cow::Borrowed(string)).ok()) } - (DuperType::TemporalPlainDateTime, DuperInner::String(string)) => { - DuperTemporal::try_plain_date_time_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainDateTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainDateTime, DuperValue::String { inner: string, .. }) => { + DuperValue::try_plain_date_time_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalPlainDateTime, DuperInner::Bytes(bytes)) => { - str::from_utf8(bytes.as_ref()) - .ok() - .and_then(|string| { - DuperTemporal::try_plain_date_time_from(Cow::Borrowed(string)).ok() - }) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainDateTime").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainDateTime, DuperValue::Bytes { inner: bytes, .. }) => { + str::from_utf8(bytes.as_ref()).ok().and_then(|string| { + DuperValue::try_plain_date_time_from(Cow::Borrowed(string)).ok() + }) } - (DuperType::TemporalPlainYearMonth, DuperInner::String(string)) => { - DuperTemporal::try_plain_year_month_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainYearMonth").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainYearMonth, DuperValue::String { inner: string, .. }) => { + DuperValue::try_plain_year_month_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalPlainYearMonth, DuperInner::Bytes(bytes)) => { - str::from_utf8(bytes.as_ref()) - .ok() - .and_then(|string| { - DuperTemporal::try_plain_year_month_from(Cow::Borrowed(string)).ok() - }) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainYearMonth").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainYearMonth, DuperValue::Bytes { inner: bytes, .. }) => { + str::from_utf8(bytes.as_ref()).ok().and_then(|string| { + DuperValue::try_plain_year_month_from(Cow::Borrowed(string)).ok() + }) } - (DuperType::TemporalPlainMonthDay, DuperInner::String(string)) => { - DuperTemporal::try_plain_month_day_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainMonthDay").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainMonthDay, DuperValue::String { inner: string, .. }) => { + DuperValue::try_plain_month_day_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalPlainMonthDay, DuperInner::Bytes(bytes)) => { - str::from_utf8(bytes.as_ref()) - .ok() - .and_then(|string| { - DuperTemporal::try_plain_month_day_from(Cow::Borrowed(string)).ok() - }) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("PlainMonthDay").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalPlainMonthDay, DuperValue::Bytes { inner: bytes, .. }) => { + str::from_utf8(bytes.as_ref()).ok().and_then(|string| { + DuperValue::try_plain_month_day_from(Cow::Borrowed(string)).ok() + }) } - (DuperType::TemporalDuration, DuperInner::String(string)) => { - DuperTemporal::try_duration_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("Duration").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalDuration, DuperValue::String { inner: string, .. }) => { + DuperValue::try_duration_from(Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalDuration, DuperInner::Bytes(bytes)) => { + (DuperType::TemporalDuration, DuperValue::Bytes { inner: bytes, .. }) => { str::from_utf8(bytes.as_ref()) .ok() - .and_then(|string| DuperTemporal::try_duration_from(Cow::Borrowed(string)).ok()) - .map(|temporal| DuperValue { - identifier: Some( - DuperIdentifier::try_from("Duration").expect("valid identifier"), - ), - inner: DuperInner::Temporal(temporal), - }) + .and_then(|string| DuperValue::try_duration_from(Cow::Borrowed(string)).ok()) } - (DuperType::TemporalUnspecified, DuperInner::String(string)) => { - DuperTemporal::try_unspecified_from(Cow::Borrowed(string.as_ref())) - .ok() - .map(|temporal| DuperValue { - identifier: None, - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalUnspecified, DuperValue::String { inner: string, .. }) => { + DuperValue::try_unspecified_from(None, Cow::Borrowed(string.as_ref())).ok() } - (DuperType::TemporalUnspecified, DuperInner::Bytes(bytes)) => { - str::from_utf8(bytes.as_ref()) - .ok() - .and_then(|string| { - DuperTemporal::try_unspecified_from(Cow::Borrowed(string)).ok() - }) - .map(|temporal| DuperValue { - identifier: None, - inner: DuperInner::Temporal(temporal), - }) + (DuperType::TemporalUnspecified, DuperValue::Bytes { inner: bytes, .. }) => { + str::from_utf8(bytes.as_ref()).ok().and_then(|string| { + DuperValue::try_unspecified_from(None, Cow::Borrowed(string)).ok() + }) } - (DuperType::Integer, DuperInner::Float(float)) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Integer(*float as i64), + ( + DuperType::Integer, + DuperValue::Float { + inner: float, + identifier, + }, + ) => Some(DuperValue::Integer { + identifier: identifier.clone(), + inner: *float as i64, }), - (DuperType::Float, DuperInner::Integer(integer)) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Float(*integer as f64), + ( + DuperType::Float, + DuperValue::Integer { + inner: integer, + identifier, + }, + ) => Some(DuperValue::Float { + identifier: identifier.clone(), + inner: *integer as f64, }), - (DuperType::Boolean, _) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Boolean(IsTruthyFilter.filter(value)), + (DuperType::Boolean, value) => Some(DuperValue::Boolean { + identifier: value.identifier(), + inner: IsTruthyFilter.filter(value), }), - (DuperType::Null, _) => Some(DuperValue { - identifier: value.identifier.clone(), - inner: DuperInner::Null, + (DuperType::Null, _) => Some(DuperValue::Null { + identifier: value.identifier(), }), // Unsupported casts diff --git a/serde_duper/src/lib.rs b/serde_duper/src/lib.rs index 059b09f..11e3a4b 100644 --- a/serde_duper/src/lib.rs +++ b/serde_duper/src/lib.rs @@ -340,10 +340,7 @@ pub use duper::serde::ser::{ Serializer, to_duper, to_string, to_string_minified, to_string_pretty, }; pub use duper::serde::temporal::TemporalString; -pub use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperInner, DuperKey, DuperObject, DuperString, - DuperTuple, DuperValue, -}; +pub use duper::{DuperIdentifier, DuperKey, DuperObject, DuperTemporal, DuperValue}; #[cfg(feature = "macros")] pub use serde_duper_macros::duper; diff --git a/serde_duper/src/types/chrono.rs b/serde_duper/src/types/chrono.rs index 2015a5e..995738d 100644 --- a/serde_duper/src/types/chrono.rs +++ b/serde_duper/src/types/chrono.rs @@ -5,14 +5,14 @@ pub mod DuperNaiveDateTime { use super::*; use ::chrono::NaiveDateTime as WrappedType; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalPlainDateTime, serde::temporal::TemporalString}; pub fn serialize(value: &WrappedType, serializer: S) -> Result where S: Serializer, { - TemporalString( - DuperTemporal::try_plain_date_time_from(Cow::Owned(format!("{value:?}"))) + TemporalString::PlainDateTime( + DuperTemporalPlainDateTime::try_from(Cow::Owned(format!("{value:?}"))) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer) @@ -23,8 +23,8 @@ pub mod DuperNaiveDateTime { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::PlainDateTime(inner) => ::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::PlainDateTime(inner) => ::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), ), typ => Err(serde_core::de::Error::invalid_value( @@ -39,7 +39,7 @@ pub mod DuperOptionNaiveDateTime { use super::*; use ::chrono::NaiveDateTime as WrappedType; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalPlainDateTime, serde::temporal::TemporalString}; pub fn serialize(value: &Option, serializer: S) -> Result where @@ -47,8 +47,8 @@ pub mod DuperOptionNaiveDateTime { Option: Serialize, { match value { - Some(value) => TemporalString( - DuperTemporal::try_plain_date_time_from(Cow::Owned(format!("{value:?}"))) + Some(value) => TemporalString::PlainDateTime( + DuperTemporalPlainDateTime::try_from(Cow::Owned(format!("{value:?}"))) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer), @@ -78,8 +78,8 @@ pub mod DuperOptionNaiveDateTime { where D: Deserializer<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::PlainDateTime(inner) => Some(::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::PlainDateTime(inner) => Some(::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) .transpose(), @@ -107,14 +107,14 @@ pub mod DuperNaiveDate { use super::*; use ::chrono::NaiveDate as WrappedType; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalPlainDate, serde::temporal::TemporalString}; pub fn serialize(value: &WrappedType, serializer: S) -> Result where S: Serializer, { - TemporalString( - DuperTemporal::try_plain_date_from(Cow::Owned(format!("{value:?}"))) + TemporalString::PlainDate( + DuperTemporalPlainDate::try_from(Cow::Owned(format!("{value:?}"))) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer) @@ -125,8 +125,8 @@ pub mod DuperNaiveDate { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::PlainDate(inner) => ::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::PlainDate(inner) => ::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), ), typ => Err(serde_core::de::Error::invalid_value( @@ -141,7 +141,7 @@ pub mod DuperOptionNaiveDate { use super::*; use ::chrono::NaiveDate as WrappedType; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalPlainDate, serde::temporal::TemporalString}; pub fn serialize(value: &Option, serializer: S) -> Result where @@ -149,8 +149,8 @@ pub mod DuperOptionNaiveDate { Option: Serialize, { match value { - Some(value) => TemporalString( - DuperTemporal::try_plain_date_from(Cow::Owned(format!("{value:?}"))) + Some(value) => TemporalString::PlainDate( + DuperTemporalPlainDate::try_from(Cow::Owned(format!("{value:?}"))) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer), @@ -181,8 +181,8 @@ pub mod DuperOptionNaiveDate { where D: Deserializer<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::PlainDate(inner) => Some(::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::PlainDate(inner) => Some(::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) .transpose(), @@ -210,14 +210,14 @@ pub mod DuperNaiveTime { use super::*; use ::chrono::NaiveTime as WrappedType; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalPlainTime, serde::temporal::TemporalString}; pub fn serialize(value: &WrappedType, serializer: S) -> Result where S: Serializer, { - TemporalString( - DuperTemporal::try_plain_time_from(Cow::Owned(format!("{value:?}"))) + TemporalString::PlainTime( + DuperTemporalPlainTime::try_from(Cow::Owned(format!("{value:?}"))) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer) @@ -228,8 +228,8 @@ pub mod DuperNaiveTime { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::PlainTime(inner) => ::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::PlainTime(inner) => ::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), ), typ => Err(serde_core::de::Error::invalid_value( @@ -244,7 +244,7 @@ pub mod DuperOptionNaiveTime { use super::*; use ::chrono::NaiveTime as WrappedType; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalPlainTime, serde::temporal::TemporalString}; pub fn serialize(value: &Option, serializer: S) -> Result where @@ -252,8 +252,8 @@ pub mod DuperOptionNaiveTime { Option: Serialize, { match value { - Some(value) => TemporalString( - DuperTemporal::try_plain_time_from(Cow::Owned(format!("{value:?}"))) + Some(value) => TemporalString::PlainTime( + DuperTemporalPlainTime::try_from(Cow::Owned(format!("{value:?}"))) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer), @@ -284,8 +284,8 @@ pub mod DuperOptionNaiveTime { where D: Deserializer<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::PlainTime(inner) => Some(::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::PlainTime(inner) => Some(::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) .transpose(), @@ -320,15 +320,15 @@ pub mod DuperDateTime { use super::*; use ::chrono::{DateTime as WrappedType, TimeZone}; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalInstant, serde::temporal::TemporalString}; pub fn serialize(value: &WrappedType, serializer: S) -> Result where S: Serializer, T: TimeZone, { - TemporalString( - DuperTemporal::try_instant_from(Cow::Owned(value.to_rfc3339())) + TemporalString::Instant( + DuperTemporalInstant::try_from(Cow::Owned(value.to_rfc3339())) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer) @@ -340,8 +340,8 @@ pub mod DuperDateTime { T: TimeZone, WrappedType: Deserialize<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::Instant(inner) => >::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::Instant(inner) => >::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), ), typ => Err(serde_core::de::Error::invalid_value( @@ -356,7 +356,7 @@ pub mod DuperOptionDateTime { use super::*; use ::chrono::{DateTime as WrappedType, TimeZone}; - use duper::{DuperTemporal, serde::temporal::TemporalString}; + use duper::{DuperTemporalInstant, serde::temporal::TemporalString}; pub fn serialize(value: &Option>, serializer: S) -> Result where @@ -365,8 +365,8 @@ pub mod DuperOptionDateTime { Option>: Serialize, { match value { - Some(value) => TemporalString( - DuperTemporal::try_instant_from(Cow::Owned(value.to_rfc3339())) + Some(value) => TemporalString::Instant( + DuperTemporalInstant::try_from(Cow::Owned(value.to_rfc3339())) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer), @@ -399,8 +399,8 @@ pub mod DuperOptionDateTime { where D: Deserializer<'de>, { - match TemporalString::deserialize(deserializer)?.0 { - DuperTemporal::Instant(inner) => Some(>::deserialize( + match TemporalString::deserialize(deserializer)? { + TemporalString::Instant(inner) => Some(>::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) .transpose(), diff --git a/serde_duper/src/types/mod.rs b/serde_duper/src/types/mod.rs index 98216c8..b7d3447 100644 --- a/serde_duper/src/types/mod.rs +++ b/serde_duper/src/types/mod.rs @@ -398,7 +398,7 @@ pub mod DuperDuration { .map_err(|error| ::custom(error))?, )) .map_err(|error| ::custom(error))?; - duper::serde::temporal::TemporalString(duration).serialize(serializer) + duper::serde::temporal::TemporalString::from(duration).serialize(serializer) } pub fn deserialize<'de, D>(deserializer: D) -> Result @@ -408,51 +408,51 @@ pub mod DuperDuration { use std::str::FromStr; let temporal = duper::serde::temporal::TemporalString::deserialize(deserializer)?; - match temporal.0 { - duper::DuperTemporal::Duration(inner) | duper::DuperTemporal::Unspecified(inner) => { - let duration = temporal_rs::Duration::from_str(inner.into_inner().as_ref()) - .map_err(|error| { - ::custom(error.to_string()) - })?; - let mut secs_rounding_options = temporal_rs::options::RoundingOptions::default(); - secs_rounding_options.largest_unit = Some(temporal_rs::options::Unit::Second); - secs_rounding_options.smallest_unit = Some(temporal_rs::options::Unit::Second); - let secs = duration - .round(secs_rounding_options, None) - .map_err(|error| { - ::custom(error.to_string()) - })?; - let nanosecs = duration.subtract(&secs).map_err(|error| { + let duration = match temporal { + duper::serde::temporal::TemporalString::Duration(inner) => { + temporal_rs::Duration::from_str(inner.as_ref()).map_err(|error| { ::custom(error.to_string()) - })?; - let mut nanosecs_rounding_options = - temporal_rs::options::RoundingOptions::default(); - nanosecs_rounding_options.largest_unit = - Some(temporal_rs::options::Unit::Nanosecond); - let nanosecs = - nanosecs - .round(nanosecs_rounding_options, None) - .map_err(|error| { - ::custom(error.to_string()) - })?; - Ok(WrappedType::new( - secs.seconds() - .try_into() - .map_err(|error: std::num::TryFromIntError| { - ::custom(error.to_string()) - })?, - nanosecs.nanoseconds().try_into().map_err( - |error: std::num::TryFromIntError| { - ::custom(error.to_string()) - }, - )?, - )) + })? } - _ => Err(::custom(format!( - "expected Temporal Duration, found {:?}", - temporal.0 - ))), - } + duper::serde::temporal::TemporalString::Unspecified(inner) => { + temporal_rs::Duration::from_str(inner.as_ref()).map_err(|error| { + ::custom(error.to_string()) + })? + } + _ => { + return Err(::custom(format!( + "expected Temporal Duration, found {:?}", + temporal + ))); + } + }; + let mut secs_rounding_options = temporal_rs::options::RoundingOptions::default(); + secs_rounding_options.largest_unit = Some(temporal_rs::options::Unit::Second); + secs_rounding_options.smallest_unit = Some(temporal_rs::options::Unit::Second); + let secs = duration + .round(secs_rounding_options, None) + .map_err(|error| ::custom(error.to_string()))?; + let nanosecs = duration + .subtract(&secs) + .map_err(|error| ::custom(error.to_string()))?; + let mut nanosecs_rounding_options = temporal_rs::options::RoundingOptions::default(); + nanosecs_rounding_options.largest_unit = Some(temporal_rs::options::Unit::Nanosecond); + let nanosecs = nanosecs + .round(nanosecs_rounding_options, None) + .map_err(|error| ::custom(error.to_string()))?; + Ok(WrappedType::new( + secs.seconds() + .try_into() + .map_err(|error: std::num::TryFromIntError| { + ::custom(error.to_string()) + })?, + nanosecs + .nanoseconds() + .try_into() + .map_err(|error: std::num::TryFromIntError| { + ::custom(error.to_string()) + })?, + )) } } #[cfg(feature = "temporal")] @@ -486,7 +486,7 @@ pub mod DuperOptionDuration { .map_err(|error| ::custom(error))?, )) .map_err(|error| ::custom(error))?; - duper::serde::temporal::TemporalString(duration).serialize(serializer) + duper::serde::temporal::TemporalString::from(duration).serialize(serializer) } None => serializer.serialize_newtype_struct("Duration", &Option::<()>::None), } @@ -512,56 +512,57 @@ pub mod DuperOptionDuration { use std::str::FromStr; let temporal = duper::serde::temporal::TemporalString::deserialize(deserializer)?; - match temporal.0 { - duper::DuperTemporal::Duration(inner) - | duper::DuperTemporal::Unspecified(inner) => { - let duration = temporal_rs::Duration::from_str(inner.into_inner().as_ref()) - .map_err(|error| { - ::custom(error.to_string()) - })?; - let mut secs_rounding_options = - temporal_rs::options::RoundingOptions::default(); - secs_rounding_options.largest_unit = - Some(temporal_rs::options::Unit::Second); - secs_rounding_options.smallest_unit = - Some(temporal_rs::options::Unit::Second); - let secs = - duration - .round(secs_rounding_options, None) - .map_err(|error| { - ::custom(error.to_string()) - })?; - let nanosecs = duration.subtract(&secs).map_err(|error| { + let duration = match temporal { + duper::serde::temporal::TemporalString::Duration(inner) => { + temporal_rs::Duration::from_str(inner.as_ref()).map_err(|error| { ::custom(error.to_string()) - })?; - let mut nanosecs_rounding_options = - temporal_rs::options::RoundingOptions::default(); - nanosecs_rounding_options.largest_unit = - Some(temporal_rs::options::Unit::Nanosecond); - let nanosecs = - nanosecs - .round(nanosecs_rounding_options, None) - .map_err(|error| { - ::custom(error.to_string()) - })?; - Ok(Some(WrappedType::new( - secs.seconds().try_into().map_err( - |error: std::num::TryFromIntError| { - ::custom(error.to_string()) - }, - )?, - nanosecs.nanoseconds().try_into().map_err( - |error: std::num::TryFromIntError| { - ::custom(error.to_string()) - }, - )?, - ))) + })? } - _ => Err(::custom(format!( - "expected Temporal Duration, found {:?}", - temporal.0 - ))), - } + duper::serde::temporal::TemporalString::Unspecified(inner) => { + temporal_rs::Duration::from_str(inner.as_ref()).map_err(|error| { + ::custom(error.to_string()) + })? + } + _ => { + return Err(::custom(format!( + "expected Temporal Duration, found {:?}", + temporal + ))); + } + }; + let mut secs_rounding_options = temporal_rs::options::RoundingOptions::default(); + secs_rounding_options.largest_unit = Some(temporal_rs::options::Unit::Second); + secs_rounding_options.smallest_unit = Some(temporal_rs::options::Unit::Second); + let secs = duration + .round(secs_rounding_options, None) + .map_err(|error| { + ::custom(error.to_string()) + })?; + let nanosecs = duration.subtract(&secs).map_err(|error| { + ::custom(error.to_string()) + })?; + let mut nanosecs_rounding_options = + temporal_rs::options::RoundingOptions::default(); + nanosecs_rounding_options.largest_unit = + Some(temporal_rs::options::Unit::Nanosecond); + let nanosecs = + nanosecs + .round(nanosecs_rounding_options, None) + .map_err(|error| { + ::custom(error.to_string()) + })?; + Ok(Some(WrappedType::new( + secs.seconds() + .try_into() + .map_err(|error: std::num::TryFromIntError| { + ::custom(error.to_string()) + })?, + nanosecs.nanoseconds().try_into().map_err( + |error: std::num::TryFromIntError| { + ::custom(error.to_string()) + }, + )?, + ))) } fn visit_none(self) -> Result diff --git a/serde_duper/src/types/temporal.rs b/serde_duper/src/types/temporal.rs index 780a262..be78a2b 100644 --- a/serde_duper/src/types/temporal.rs +++ b/serde_duper/src/types/temporal.rs @@ -8,8 +8,8 @@ pub mod DuperInstant { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_instant_from(::std::borrow::Cow::Owned( + ::duper::serde::temporal::TemporalString::Instant( + ::duper::DuperTemporalInstant::try_from(::std::borrow::Cow::Owned( value .to_ixdtf_string(None, Default::default()) .map_err(|err| ::custom(err.to_string()))?, @@ -24,8 +24,8 @@ pub mod DuperInstant { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::Instant(inner) => ::deserialize( + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::Instant(inner) => ::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), ), typ => Err(serde_core::de::Error::invalid_value( @@ -44,8 +44,8 @@ pub mod DuperOptionInstant { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_instant_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::Instant( + ::duper::DuperTemporalInstant::try_from(::std::borrow::Cow::Owned( value .to_ixdtf_string(None, Default::default()) .map_err(|err| { @@ -83,11 +83,13 @@ pub mod DuperOptionInstant { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::Instant(inner) => Some(::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - )) - .transpose(), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::Instant(inner) => { + Some(::deserialize( + serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), + )) + .transpose() + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"Instant", @@ -115,8 +117,8 @@ pub mod DuperZonedDateTime { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_zoned_date_time_from(::std::borrow::Cow::Owned( + ::duper::serde::temporal::TemporalString::ZonedDateTime( + ::duper::DuperTemporalZonedDateTime::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -129,10 +131,12 @@ pub mod DuperZonedDateTime { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::ZonedDateTime(inner) => ::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - ), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::ZonedDateTime(inner) => { + ::deserialize(serde_core::de::IntoDeserializer::into_deserializer( + inner.as_ref(), + )) + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainTime", @@ -149,8 +153,8 @@ pub mod DuperOptionZonedDateTime { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_zoned_date_time_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::ZonedDateTime( + ::duper::DuperTemporalZonedDateTime::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -184,8 +188,8 @@ pub mod DuperOptionZonedDateTime { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::ZonedDateTime(inner) => { + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::ZonedDateTime(inner) => { Some(::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) @@ -218,11 +222,9 @@ pub mod DuperPlainDate { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_date_from(::std::borrow::Cow::Owned( - value.to_string(), - )) - .map_err(|err| ::custom(err.to_string()))?, + ::duper::serde::temporal::TemporalString::PlainDate( + ::duper::DuperTemporalPlainDate::try_from(::std::borrow::Cow::Owned(value.to_string())) + .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer) } @@ -232,10 +234,12 @@ pub mod DuperPlainDate { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainDate(inner) => ::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - ), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainDate(inner) => { + ::deserialize(serde_core::de::IntoDeserializer::into_deserializer( + inner.as_ref(), + )) + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainTime", @@ -252,8 +256,8 @@ pub mod DuperOptionPlainDate { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_date_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::PlainDate( + ::duper::DuperTemporalPlainDate::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -287,11 +291,13 @@ pub mod DuperOptionPlainDate { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainDate(inner) => Some(::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - )) - .transpose(), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainDate(inner) => { + Some(::deserialize( + serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), + )) + .transpose() + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainDate", @@ -319,8 +325,8 @@ pub mod DuperPlainTime { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_time_from(::std::borrow::Cow::Owned( + ::duper::serde::temporal::TemporalString::PlainTime( + ::duper::DuperTemporalPlainTime::try_from(::std::borrow::Cow::Owned( value .to_ixdtf_string(Default::default()) .map_err(|err| ::custom(err.to_string()))?, @@ -335,10 +341,12 @@ pub mod DuperPlainTime { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainTime(inner) => ::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - ), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainTime(inner) => { + ::deserialize(serde_core::de::IntoDeserializer::into_deserializer( + inner.as_ref(), + )) + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainTime", @@ -355,8 +363,8 @@ pub mod DuperOptionPlainTime { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_time_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::PlainTime( + ::duper::DuperTemporalPlainTime::try_from(::std::borrow::Cow::Owned( value.to_ixdtf_string(Default::default()).map_err(|err| { ::custom(err.to_string()) })?, @@ -392,11 +400,13 @@ pub mod DuperOptionPlainTime { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainTime(inner) => Some(::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - )) - .transpose(), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainTime(inner) => { + Some(::deserialize( + serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), + )) + .transpose() + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainTime", @@ -424,8 +434,8 @@ pub mod DuperPlainDateTime { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_date_time_from(::std::borrow::Cow::Owned( + ::duper::serde::temporal::TemporalString::PlainDateTime( + ::duper::DuperTemporalPlainDateTime::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -438,10 +448,12 @@ pub mod DuperPlainDateTime { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainDateTime(inner) => ::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - ), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainDateTime(inner) => { + ::deserialize(serde_core::de::IntoDeserializer::into_deserializer( + inner.as_ref(), + )) + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainDateTime", @@ -458,8 +470,8 @@ pub mod DuperOptionPlainDateTime { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_date_time_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::PlainDateTime( + ::duper::DuperTemporalPlainDateTime::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -493,8 +505,8 @@ pub mod DuperOptionPlainDateTime { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainDateTime(inner) => { + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainDateTime(inner) => { Some(::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) @@ -527,8 +539,8 @@ pub mod DuperPlainYearMonth { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_year_month_from(::std::borrow::Cow::Owned( + ::duper::serde::temporal::TemporalString::PlainYearMonth( + ::duper::DuperTemporalPlainYearMonth::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -541,10 +553,12 @@ pub mod DuperPlainYearMonth { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainYearMonth(inner) => ::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - ), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainYearMonth(inner) => { + ::deserialize(serde_core::de::IntoDeserializer::into_deserializer( + inner.as_ref(), + )) + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainYearMonth", @@ -561,8 +575,8 @@ pub mod DuperOptionPlainYearMonth { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_year_month_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::PlainYearMonth( + ::duper::DuperTemporalPlainYearMonth::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -596,8 +610,8 @@ pub mod DuperOptionPlainYearMonth { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainYearMonth(inner) => { + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainYearMonth(inner) => { Some(::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) @@ -630,8 +644,8 @@ pub mod DuperPlainMonthDay { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_month_day_from(::std::borrow::Cow::Owned( + ::duper::serde::temporal::TemporalString::PlainMonthDay( + ::duper::DuperTemporalPlainMonthDay::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -644,10 +658,12 @@ pub mod DuperPlainMonthDay { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainMonthDay(inner) => ::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - ), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainMonthDay(inner) => { + ::deserialize(serde_core::de::IntoDeserializer::into_deserializer( + inner.as_ref(), + )) + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"PlainMonthDay", @@ -664,8 +680,8 @@ pub mod DuperOptionPlainMonthDay { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_plain_month_day_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::PlainMonthDay( + ::duper::DuperTemporalPlainMonthDay::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -699,8 +715,8 @@ pub mod DuperOptionPlainMonthDay { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::PlainMonthDay(inner) => { + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::PlainMonthDay(inner) => { Some(::deserialize( serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), )) @@ -733,8 +749,8 @@ pub mod DuperDuration { where S: Serializer, { - ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_duration_from(::std::borrow::Cow::Owned(value.to_string())) + ::duper::serde::temporal::TemporalString::Duration( + ::duper::DuperTemporalDuration::try_from(::std::borrow::Cow::Owned(value.to_string())) .map_err(|err| ::custom(err.to_string()))?, ) .serialize(serializer) @@ -745,10 +761,12 @@ pub mod DuperDuration { D: Deserializer<'de>, WrappedType: Deserialize<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::Duration(inner) => ::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - ), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::Duration(inner) => { + ::deserialize(serde_core::de::IntoDeserializer::into_deserializer( + inner.as_ref(), + )) + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"Duration", @@ -765,8 +783,8 @@ pub mod DuperOptionDuration { S: Serializer, { match value { - Some(value) => ::duper::serde::temporal::TemporalString( - ::duper::DuperTemporal::try_duration_from(::std::borrow::Cow::Owned( + Some(value) => ::duper::serde::temporal::TemporalString::Duration( + ::duper::DuperTemporalDuration::try_from(::std::borrow::Cow::Owned( value.to_string(), )) .map_err(|err| ::custom(err.to_string()))?, @@ -800,11 +818,13 @@ pub mod DuperOptionDuration { where D: Deserializer<'de>, { - match ::duper::serde::temporal::TemporalString::deserialize(deserializer)?.0 { - ::duper::DuperTemporal::Duration(inner) => Some(::deserialize( - serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), - )) - .transpose(), + match ::duper::serde::temporal::TemporalString::deserialize(deserializer)? { + ::duper::serde::temporal::TemporalString::Duration(inner) => { + Some(::deserialize( + serde_core::de::IntoDeserializer::into_deserializer(inner.as_ref()), + )) + .transpose() + } typ => Err(serde_core::de::Error::invalid_value( serde_core::de::Unexpected::Str(typ.name()), &"Duration", diff --git a/tracing_duper/src/lib.rs b/tracing_duper/src/lib.rs index 8379671..af43a29 100644 --- a/tracing_duper/src/lib.rs +++ b/tracing_duper/src/lib.rs @@ -66,12 +66,7 @@ use std::{ #[cfg(feature = "chrono")] use chrono::{Local, Utc}; -#[cfg(feature = "chrono")] -use duper::DuperTemporal; -use duper::{ - DuperArray, DuperBytes, DuperIdentifier, DuperInner, DuperKey, DuperObject, DuperString, - DuperValue, Serializer, -}; +use duper::{DuperIdentifier, DuperKey, DuperObject, DuperValue, Serializer}; use tracing_core::{Event, Subscriber, field}; use tracing_subscriber::{Layer, field::VisitOutput, registry::LookupSpan}; @@ -95,13 +90,10 @@ pub struct ChronoUtcTimer; #[cfg(feature = "chrono")] impl DuperTimer for ChronoUtcTimer { fn get_timestamp(&self) -> Option> { - Some(DuperValue { - identifier: Some(DuperIdentifier::try_from("Instant").expect("valid identifier")), - inner: DuperInner::Temporal( - DuperTemporal::try_instant_from(Cow::Owned(Utc::now().to_rfc3339())) - .expect("valid ISO-8601 Instant"), - ), - }) + Some( + DuperValue::try_instant_from(Cow::Owned(Utc::now().to_rfc3339())) + .expect("valid ISO-8601 Instant"), + ) } } @@ -112,13 +104,10 @@ pub struct ChronoLocalTimer; #[cfg(feature = "chrono")] impl DuperTimer for ChronoLocalTimer { fn get_timestamp(&self) -> Option> { - Some(DuperValue { - identifier: Some(DuperIdentifier::try_from("Instant").expect("valid identifier")), - inner: DuperInner::Temporal( - DuperTemporal::try_instant_from(Cow::Owned(Local::now().to_rfc3339())) - .expect("valid ISO-8601 Instant"), - ), - }) + Some( + DuperValue::try_instant_from(Cow::Owned(Local::now().to_rfc3339())) + .expect("valid ISO-8601 Instant"), + ) } } @@ -370,9 +359,9 @@ where let mut visitor = DuperVisitor::new(); visitor.values.insert( DuperKey::from("span_id"), - DuperValue { + DuperValue::Integer { identifier: None, - inner: DuperInner::Integer(id.into_u64() as i64), + inner: id.into_u64() as i64, }, ); attrs.record(&mut visitor); @@ -415,9 +404,9 @@ where if self.display_level { log.push(( DuperKey::from("level"), - DuperValue { + DuperValue::String { identifier: None, - inner: DuperInner::String(DuperString::from(metadata.level().as_str())), + inner: Cow::Borrowed(metadata.level().as_str()), }, )); } @@ -431,9 +420,9 @@ where if self.display_target { log.push(( DuperKey::from("target"), - DuperValue { + DuperValue::String { identifier: None, - inner: DuperInner::String(DuperString::from(metadata.target())), + inner: Cow::Borrowed(metadata.target()), }, )); } @@ -441,26 +430,26 @@ where if self.display_file { log.push(( DuperKey::from("file"), - DuperValue { - identifier: None, - inner: metadata - .file() - .map(|file| DuperInner::String(DuperString::from(file))) - .unwrap_or(DuperInner::Null), - }, + metadata + .file() + .map(|file| DuperValue::String { + identifier: None, + inner: Cow::Borrowed(file), + }) + .unwrap_or(DuperValue::Null { identifier: None }), )); } if self.display_line { log.push(( DuperKey::from("line"), - DuperValue { - identifier: None, - inner: metadata - .line() - .map(|line| DuperInner::Integer(line.into())) - .unwrap_or(DuperInner::Null), - }, + metadata + .line() + .map(|line| DuperValue::Integer { + identifier: None, + inner: line.into(), + }) + .unwrap_or(DuperValue::Null { identifier: None }), )); } @@ -476,9 +465,9 @@ where { log.push(( DuperKey::from("span"), - DuperValue { + DuperValue::Object { identifier: None, - inner: DuperInner::Object(fields.0.clone()), + inner: fields.0.clone(), }, )); } @@ -488,18 +477,18 @@ where for span in scope.from_root() { let extensions = span.extensions(); if let Some(fields) = extensions.get::() { - spans.push(DuperValue { + spans.push(DuperValue::Object { identifier: None, - inner: DuperInner::Object(fields.0.clone()), + inner: fields.0.clone(), }); } } } log.push(( DuperKey::from("spans"), - DuperValue { + DuperValue::Array { identifier: None, - inner: DuperInner::Array(DuperArray::from(spans)), + inner: spans, }, )); } @@ -514,9 +503,9 @@ where } else { log.push(( DuperKey::from("fields"), - DuperValue { + DuperValue::Object { identifier: None, - inner: DuperInner::Object(object), + inner: object, }, )); } @@ -525,9 +514,9 @@ where if let Err(error) = writeln!( self.make_writer.make_writer_for(event.metadata()), "{}", - serializer.serialize(&DuperValue { + serializer.serialize(&DuperValue::Object { identifier: None, - inner: DuperInner::Object(DuperObject::from_lossy(log)), + inner: DuperObject::from_lossy(log), }) ) { let _ = error; @@ -660,9 +649,9 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { } self.values.insert( key, - DuperValue { + DuperValue::String { identifier: None, - inner: DuperInner::String(DuperString::from(format!("{:?}", value))), + inner: Cow::Owned(format!("{:?}", value)), }, ); } @@ -674,9 +663,9 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { } self.values.insert( key, - DuperValue { + DuperValue::Float { identifier: None, - inner: DuperInner::Float(value), + inner: value, }, ); } @@ -688,9 +677,9 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { } self.values.insert( key, - DuperValue { + DuperValue::Integer { identifier: None, - inner: DuperInner::Integer(value), + inner: value, }, ); } @@ -703,17 +692,17 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { if let Ok(value) = i64::try_from(value) { self.values.insert( key, - DuperValue { + DuperValue::Integer { identifier: None, - inner: DuperInner::Integer(value), + inner: value, }, ); } else { self.values.insert( key, - DuperValue { + DuperValue::String { identifier: Some(DuperIdentifier::try_from("U64").expect("valid identifier")), - inner: DuperInner::String(DuperString::from(value.to_string())), + inner: Cow::Owned(value.to_string()), }, ); } @@ -727,17 +716,17 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { if let Ok(value) = i64::try_from(value) { self.values.insert( key, - DuperValue { + DuperValue::Integer { identifier: None, - inner: DuperInner::Integer(value), + inner: value, }, ); } else { self.values.insert( key, - DuperValue { + DuperValue::String { identifier: Some(DuperIdentifier::try_from("I128").expect("valid identifier")), - inner: DuperInner::String(DuperString::from(value.to_string())), + inner: Cow::Owned(value.to_string()), }, ); } @@ -752,17 +741,17 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { if let Ok(value) = i64::try_from(value) { self.values.insert( key, - DuperValue { + DuperValue::Integer { identifier: None, - inner: DuperInner::Integer(value), + inner: value, }, ); } else { self.values.insert( key, - DuperValue { + DuperValue::String { identifier: Some(DuperIdentifier::try_from("U128").expect("valid identifier")), - inner: DuperInner::String(DuperString::from(value.to_string())), + inner: Cow::Owned(value.to_string()), }, ); } @@ -775,9 +764,9 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { } self.values.insert( key, - DuperValue { + DuperValue::Boolean { identifier: None, - inner: DuperInner::Boolean(value), + inner: value, }, ); } @@ -799,9 +788,9 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { } self.values.insert( key, - DuperValue { + DuperValue::String { identifier: None, - inner: DuperInner::String(DuperString::from(value.to_string())), + inner: Cow::Owned(value.to_string()), }, ); } @@ -814,9 +803,9 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { } self.values.insert( key, - DuperValue { + DuperValue::Bytes { identifier: None, - inner: DuperInner::Bytes(DuperBytes::from(value.to_vec())), + inner: Cow::Owned(value.to_vec()), }, ); } @@ -832,9 +821,9 @@ impl tracing_core::field::Visit for DuperVisitor<'_> { } self.values.insert( key, - DuperValue { + DuperValue::String { identifier: Some(DuperIdentifier::try_from("Error").expect("valid identifier")), - inner: DuperInner::String(DuperString::from(value.to_string())), + inner: Cow::Owned(value.to_string()), }, ); }