diff --git a/Cargo.lock b/Cargo.lock index 9db0c94e..2488bd6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -867,6 +867,7 @@ dependencies = [ "oxiri", "oxsdatatypes", "rand", + "serde", "thiserror", ] @@ -898,6 +899,7 @@ name = "oxsdatatypes" version = "0.2.0-alpha.1" dependencies = [ "js-sys", + "serde", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 4e8ea772..0d3a87ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ rust-version = "1.70" [workspace.dependencies] rocksdb = {git = "https://git.nextgraph.org/NextGraph/rust-rocksdb.git", branch = "master", features = [ ] } +serde = { version = "1.0.142", features = ["derive"] } anyhow = "1.0.72" arbitrary = "1.3" assert_cmd = "2.0" diff --git a/lib/oxrdf/Cargo.toml b/lib/oxrdf/Cargo.toml index 12b4ba60..23622471 100644 --- a/lib/oxrdf/Cargo.toml +++ b/lib/oxrdf/Cargo.toml @@ -23,6 +23,7 @@ oxiri.workspace = true oxsdatatypes = { workspace = true, optional = true } rand.workspace = true thiserror.workspace = true +serde.workspace = true [lints] workspace = true diff --git a/lib/oxrdf/src/blank_node.rs b/lib/oxrdf/src/blank_node.rs index 4bf82391..2fe02c26 100644 --- a/lib/oxrdf/src/blank_node.rs +++ b/lib/oxrdf/src/blank_node.rs @@ -1,4 +1,5 @@ use rand::random; +use serde::{Deserialize, Serialize}; use std::io::Write; use std::{fmt, str}; @@ -16,10 +17,10 @@ use std::{fmt, str}; /// assert_eq!("_:a122", BlankNode::new("a122")?.to_string()); /// # Result::<_,oxrdf::BlankNodeIdParseError>::Ok(()) /// ``` -#[derive(Eq, PartialEq, Debug, Clone, Hash)] +#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize)] pub struct BlankNode(BlankNodeContent); -#[derive(PartialEq, Eq, Debug, Clone, Hash)] +#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)] enum BlankNodeContent { Named(String), Anonymous { id: u128, str: IdStr }, @@ -246,7 +247,7 @@ impl PartialEq> for BlankNode { } } -#[derive(PartialEq, Eq, Debug, Clone, Hash)] +#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)] struct IdStr([u8; 32]); impl IdStr { diff --git a/lib/oxrdf/src/literal.rs b/lib/oxrdf/src/literal.rs index 5f7ab9e0..d59855fe 100644 --- a/lib/oxrdf/src/literal.rs +++ b/lib/oxrdf/src/literal.rs @@ -3,6 +3,7 @@ use crate::vocab::{rdf, xsd}; use oxilangtag::{LanguageTag, LanguageTagParseError}; #[cfg(feature = "oxsdatatypes")] use oxsdatatypes::*; +use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::fmt; use std::fmt::Write; @@ -31,10 +32,10 @@ use std::fmt::Write; /// ); /// # Result::<(), LanguageTagParseError>::Ok(()) /// ``` -#[derive(Eq, PartialEq, Debug, Clone, Hash)] +#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize)] pub struct Literal(LiteralContent); -#[derive(PartialEq, Eq, Debug, Clone, Hash)] +#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)] enum LiteralContent { String(String), LanguageTaggedString { value: String, language: String }, diff --git a/lib/oxrdf/src/named_node.rs b/lib/oxrdf/src/named_node.rs index 9b545bcc..41a55169 100644 --- a/lib/oxrdf/src/named_node.rs +++ b/lib/oxrdf/src/named_node.rs @@ -1,4 +1,5 @@ use oxiri::{Iri, IriParseError}; +use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt; @@ -14,7 +15,7 @@ use std::fmt; /// ); /// # Result::<_,oxrdf::IriParseError>::Ok(()) /// ``` -#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash, Serialize, Deserialize)] pub struct NamedNode { iri: String, } diff --git a/lib/oxrdf/src/triple.rs b/lib/oxrdf/src/triple.rs index d5526c19..a27057b2 100644 --- a/lib/oxrdf/src/triple.rs +++ b/lib/oxrdf/src/triple.rs @@ -2,10 +2,11 @@ use crate::blank_node::BlankNode; use crate::literal::Literal; use crate::named_node::NamedNode; use crate::{BlankNodeRef, LiteralRef, NamedNodeRef}; +use serde::{Deserialize, Serialize}; use std::fmt; /// The owned union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node). -#[derive(Eq, PartialEq, Debug, Clone, Hash)] +#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize)] pub enum NamedOrBlankNode { NamedNode(NamedNode), BlankNode(BlankNode), @@ -152,7 +153,7 @@ impl<'a> From> for NamedOrBlankNode { } /// The owned union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) (if the `rdf-star` feature is enabled). -#[derive(Eq, PartialEq, Debug, Clone, Hash)] +#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize)] pub enum Subject { NamedNode(NamedNode), BlankNode(BlankNode), @@ -382,7 +383,7 @@ impl<'a> From<&'a NamedOrBlankNode> for SubjectRef<'a> { /// An owned RDF [term](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) /// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node), [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) (if the `rdf-star` feature is enabled). -#[derive(Eq, PartialEq, Debug, Clone, Hash)] +#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize)] pub enum Term { NamedNode(NamedNode), BlankNode(BlankNode), @@ -937,7 +938,7 @@ impl<'a> From> for Triple { /// A possible owned graph name. /// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node), and the [default graph name](https://www.w3.org/TR/rdf11-concepts/#dfn-default-graph). -#[derive(Eq, PartialEq, Debug, Clone, Hash, Default)] +#[derive(Eq, PartialEq, Debug, Clone, Hash, Default, Serialize, Deserialize)] pub enum GraphName { NamedNode(NamedNode), BlankNode(BlankNode), diff --git a/lib/oxsdatatypes/Cargo.toml b/lib/oxsdatatypes/Cargo.toml index d0e8aafd..184b5d77 100644 --- a/lib/oxsdatatypes/Cargo.toml +++ b/lib/oxsdatatypes/Cargo.toml @@ -19,6 +19,7 @@ custom-now = [] [dependencies] thiserror.workspace = true +serde.workspace = true [target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies] js-sys = { workspace = true, optional = true } diff --git a/lib/oxsdatatypes/src/boolean.rs b/lib/oxsdatatypes/src/boolean.rs index c881765c..4a0c0d37 100644 --- a/lib/oxsdatatypes/src/boolean.rs +++ b/lib/oxsdatatypes/src/boolean.rs @@ -1,11 +1,14 @@ use crate::{Decimal, Double, Float, Integer}; +use serde::{Deserialize, Serialize}; use std::fmt; use std::str::{FromStr, ParseBoolError}; /// [XML Schema `boolean` datatype](https://www.w3.org/TR/xmlschema11-2/#boolean) /// /// Uses internally a [`bool`]. -#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive( + Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, +)] #[repr(transparent)] pub struct Boolean { value: bool, diff --git a/lib/oxsdatatypes/src/date_time.rs b/lib/oxsdatatypes/src/date_time.rs index 579f72b7..ad5e888d 100644 --- a/lib/oxsdatatypes/src/date_time.rs +++ b/lib/oxsdatatypes/src/date_time.rs @@ -1,6 +1,7 @@ #![allow(clippy::expect_used)] use crate::{DayTimeDuration, Decimal, Duration, YearMonthDuration}; +use serde::{Deserialize, Serialize}; use std::cmp::{min, Ordering}; use std::fmt; use std::hash::{Hash, Hasher}; @@ -10,7 +11,7 @@ use std::str::FromStr; /// /// It encodes the value using a number of seconds from the Gregorian calendar era using a [`Decimal`] /// and an optional timezone offset in minutes. -#[derive(Eq, PartialEq, PartialOrd, Debug, Clone, Copy, Hash)] +#[derive(Eq, PartialEq, PartialOrd, Debug, Clone, Copy, Hash, Serialize, Deserialize)] pub struct DateTime { timestamp: Timestamp, } @@ -1452,7 +1453,7 @@ impl fmt::Display for GDay { /// A timezone offset with respect to UTC. /// /// It is encoded as a number of minutes between -PT14H and PT14H. -#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash, Serialize, Deserialize)] pub struct TimezoneOffset { offset: i16, // in minute with respect to UTC } @@ -1562,7 +1563,7 @@ struct DateTimeSevenPropertyModel { timezone_offset: Option, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] struct Timestamp { value: Decimal, timezone_offset: Option, @@ -3140,7 +3141,7 @@ mod tests { fn custom_now() { #[allow(unsafe_code)] #[no_mangle] - extern "Rust" fn custom_ox_now() -> Duration { + fn custom_ox_now() -> Duration { Duration::default() } DateTime::now(); diff --git a/lib/oxsdatatypes/src/decimal.rs b/lib/oxsdatatypes/src/decimal.rs index 3383ad48..a8f1016d 100644 --- a/lib/oxsdatatypes/src/decimal.rs +++ b/lib/oxsdatatypes/src/decimal.rs @@ -1,4 +1,5 @@ use crate::{Boolean, Double, Float, Integer, TooLargeForIntegerError}; +use serde::{Deserialize, Serialize}; use std::fmt; use std::fmt::Write; use std::str::FromStr; @@ -12,7 +13,9 @@ const DECIMAL_PART_POW_MINUS_ONE: i128 = 100_000_000_000_000_000; /// It stores the decimal in a fix point encoding allowing nearly 18 digits before and 18 digits after ".". /// /// It stores the value in a [`i128`] integer after multiplying it by 10¹⁸. -#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash, Default)] +#[derive( + Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash, Default, Serialize, Deserialize, +)] pub struct Decimal { value: i128, // value * 10^18 } diff --git a/lib/oxsdatatypes/src/double.rs b/lib/oxsdatatypes/src/double.rs index 12937ada..fe6ac762 100644 --- a/lib/oxsdatatypes/src/double.rs +++ b/lib/oxsdatatypes/src/double.rs @@ -1,4 +1,5 @@ use crate::{Boolean, Float, Integer}; +use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt; use std::num::ParseFloatError; @@ -10,7 +11,7 @@ use std::str::FromStr; /// Uses internally a [`f64`]. /// ///
Serialization does not follow the canonical mapping.
-#[derive(Debug, Clone, Copy, Default, PartialEq)] +#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)] #[repr(transparent)] pub struct Double { value: f64, diff --git a/lib/oxsdatatypes/src/duration.rs b/lib/oxsdatatypes/src/duration.rs index 719bfad2..b42bf7e2 100644 --- a/lib/oxsdatatypes/src/duration.rs +++ b/lib/oxsdatatypes/src/duration.rs @@ -1,4 +1,5 @@ use crate::{DateTime, Decimal}; +use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt; use std::str::FromStr; @@ -7,7 +8,7 @@ use std::time::Duration as StdDuration; /// [XML Schema `duration` datatype](https://www.w3.org/TR/xmlschema11-2/#duration) /// /// It stores the duration using a pair of a [`YearMonthDuration`] and a [`DayTimeDuration`]. -#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash, Default)] +#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash, Default, Serialize, Deserialize)] pub struct Duration { year_month: YearMonthDuration, day_time: DayTimeDuration, @@ -293,7 +294,9 @@ impl PartialOrd for Duration { /// [XML Schema `yearMonthDuration` datatype](https://www.w3.org/TR/xmlschema11-2/#yearMonthDuration) /// /// It stores the duration as a number of months encoded using a [`i64`]. -#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash, Default)] +#[derive( + Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash, Default, Serialize, Deserialize, +)] pub struct YearMonthDuration { months: i64, } @@ -460,7 +463,9 @@ impl PartialOrd for Duration { /// [XML Schema `dayTimeDuration` datatype](https://www.w3.org/TR/xmlschema11-2/#dayTimeDuration) /// /// It stores the duration as a number of seconds encoded using a [`Decimal`]. -#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash, Default)] +#[derive( + Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy, Hash, Default, Serialize, Deserialize, +)] pub struct DayTimeDuration { seconds: Decimal, } diff --git a/lib/oxsdatatypes/src/float.rs b/lib/oxsdatatypes/src/float.rs index 99274316..83922c02 100644 --- a/lib/oxsdatatypes/src/float.rs +++ b/lib/oxsdatatypes/src/float.rs @@ -1,4 +1,5 @@ use crate::{Boolean, Double, Integer}; +use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt; use std::num::ParseFloatError; @@ -10,7 +11,7 @@ use std::str::FromStr; /// Uses internally a [`f32`]. /// ///
Serialization does not follow the canonical mapping.
-#[derive(Debug, Clone, Copy, Default, PartialEq)] +#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)] #[repr(transparent)] pub struct Float { value: f32, diff --git a/lib/oxsdatatypes/src/integer.rs b/lib/oxsdatatypes/src/integer.rs index 6e01d1f2..6df15362 100644 --- a/lib/oxsdatatypes/src/integer.rs +++ b/lib/oxsdatatypes/src/integer.rs @@ -1,4 +1,5 @@ use crate::{Boolean, Decimal, Double, Float}; +use serde::{Deserialize, Serialize}; use std::fmt; use std::num::ParseIntError; use std::str::FromStr; @@ -6,7 +7,9 @@ use std::str::FromStr; /// [XML Schema `integer` datatype](https://www.w3.org/TR/xmlschema11-2/#integer) /// /// Uses internally a [`i64`]. -#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive( + Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, +)] #[repr(transparent)] pub struct Integer { value: i64,