Adds native support for all time related XSD literals

pull/46/head
Tpt 4 years ago
parent beebcdfbd6
commit f9d97a2296
  1. 58
      lib/src/model/literal.rs
  2. 550
      lib/src/model/xsd/date_time.rs
  3. 2
      lib/src/model/xsd/mod.rs
  4. 55
      lib/src/model/xsd/parser.rs
  5. 172
      lib/src/sparql/eval.rs
  6. 91
      lib/src/store/binary_encoder.rs
  7. 117
      lib/src/store/numeric_encoder.rs

@ -268,11 +268,11 @@ impl From<Decimal> for Literal {
} }
} }
impl From<Date> for Literal { impl From<DateTime> for Literal {
fn from(value: Date) -> Self { fn from(value: DateTime) -> Self {
Literal(LiteralContent::TypedLiteral { Literal(LiteralContent::TypedLiteral {
value: value.to_string(), value: value.to_string(),
datatype: xsd::DATE.into(), datatype: xsd::DATE_TIME.into(),
}) })
} }
} }
@ -286,11 +286,56 @@ impl From<Time> for Literal {
} }
} }
impl From<DateTime> for Literal { impl From<Date> for Literal {
fn from(value: DateTime) -> Self { fn from(value: Date) -> Self {
Literal(LiteralContent::TypedLiteral { Literal(LiteralContent::TypedLiteral {
value: value.to_string(), value: value.to_string(),
datatype: xsd::DATE_TIME.into(), datatype: xsd::DATE.into(),
})
}
}
impl From<GYearMonth> for Literal {
fn from(value: GYearMonth) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::G_YEAR_MONTH.into(),
})
}
}
impl From<GYear> for Literal {
fn from(value: GYear) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::G_YEAR.into(),
})
}
}
impl From<GMonthDay> for Literal {
fn from(value: GMonthDay) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::G_MONTH_DAY.into(),
})
}
}
impl From<GMonth> for Literal {
fn from(value: GMonth) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::G_MONTH.into(),
})
}
}
impl From<GDay> for Literal {
fn from(value: GDay) -> Self {
Literal(LiteralContent::TypedLiteral {
value: value.to_string(),
datatype: xsd::G_DAY.into(),
}) })
} }
} }
@ -312,6 +357,7 @@ impl From<YearMonthDuration> for Literal {
}) })
} }
} }
impl From<DayTimeDuration> for Literal { impl From<DayTimeDuration> for Literal {
fn from(value: DayTimeDuration) -> Self { fn from(value: DayTimeDuration) -> Self {
Literal(LiteralContent::TypedLiteral { Literal(LiteralContent::TypedLiteral {

@ -1,5 +1,9 @@
use super::parser::{date_lexical_rep, date_time_lexical_rep, parse_value, time_lexical_rep}; use super::parser::{date_lexical_rep, date_time_lexical_rep, parse_value, time_lexical_rep};
use super::{DayTimeDuration, Decimal, Duration, XsdParseError, YearMonthDuration}; use super::{DayTimeDuration, Decimal, Duration, XsdParseError, YearMonthDuration};
use crate::model::xsd::parser::{
g_day_lexical_rep, g_month_day_lexical_rep, g_month_lexical_rep, g_year_lexical_rep,
g_year_month_lexical_rep,
};
use std::cmp::{min, Ordering}; use std::cmp::{min, Ordering};
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::error::Error; use std::error::Error;
@ -166,6 +170,10 @@ impl DateTime {
}) })
} }
} }
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
} }
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes). /// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
@ -327,6 +335,10 @@ impl Time {
.try_into() .try_into()
.ok() .ok()
} }
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
} }
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes). /// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
@ -475,6 +487,10 @@ impl Date {
.try_into() .try_into()
.ok() .ok()
} }
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
} }
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes). /// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
@ -513,6 +529,499 @@ impl fmt::Display for Date {
} }
} }
/// [XML Schema `gYearMonth` datatype](https://www.w3.org/TR/xmlschema11-2/#gYearMonth) implementation.
#[derive(Eq, PartialEq, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct GYearMonth {
timestamp: Timestamp,
}
impl GYearMonth {
pub(super) fn new(
year: i64,
month: u8,
timezone_offset: Option<TimezoneOffset>,
) -> Result<Self, DateTimeError> {
Ok(Self {
timestamp: Timestamp::new(&DateTimeSevenPropertyModel {
year: Some(year),
month: Some(month),
day: None,
hour: None,
minute: None,
second: None,
timezone_offset,
})?,
})
}
pub fn from_be_bytes(bytes: [u8; 18]) -> Self {
Self {
timestamp: Timestamp::from_be_bytes(bytes),
}
}
pub fn year(&self) -> i64 {
self.timestamp.year()
}
pub fn month(&self) -> u8 {
self.timestamp.month()
}
pub fn timezone(&self) -> Option<DayTimeDuration> {
Some(self.timezone_offset()?.into())
}
pub fn timezone_offset(&self) -> Option<TimezoneOffset> {
self.timestamp.timezone_offset()
}
pub fn to_be_bytes(&self) -> [u8; 18] {
self.timestamp.to_be_bytes()
}
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<DateTime> for GYearMonth {
type Error = DateTimeError;
fn try_from(date_time: DateTime) -> Result<Self, DateTimeError> {
GYearMonth::new(
date_time.year(),
date_time.month(),
date_time.timezone_offset(),
)
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<Date> for GYearMonth {
type Error = DateTimeError;
fn try_from(date: Date) -> Result<Self, DateTimeError> {
GYearMonth::new(date.year(), date.month(), date.timezone_offset())
}
}
impl FromStr for GYearMonth {
type Err = XsdParseError;
fn from_str(input: &str) -> Result<Self, XsdParseError> {
parse_value(g_year_month_lexical_rep, input)
}
}
impl fmt::Display for GYearMonth {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let year = self.year();
if year < 0 {
write!(f, "-")?;
}
write!(f, "{:04}-{:02}", year.abs(), self.month())?;
if let Some(timezone_offset) = self.timezone_offset() {
write!(f, "{}", timezone_offset)?;
}
Ok(())
}
}
/// [XML Schema `gYear` datatype](https://www.w3.org/TR/xmlschema11-2/#gYear) implementation.
#[derive(Eq, PartialEq, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct GYear {
timestamp: Timestamp,
}
impl GYear {
pub(super) fn new(
year: i64,
timezone_offset: Option<TimezoneOffset>,
) -> Result<Self, DateTimeError> {
Ok(Self {
timestamp: Timestamp::new(&DateTimeSevenPropertyModel {
year: Some(year),
month: None,
day: None,
hour: None,
minute: None,
second: None,
timezone_offset,
})?,
})
}
pub fn from_be_bytes(bytes: [u8; 18]) -> Self {
Self {
timestamp: Timestamp::from_be_bytes(bytes),
}
}
pub fn year(&self) -> i64 {
self.timestamp.year()
}
pub fn timezone(&self) -> Option<DayTimeDuration> {
Some(self.timezone_offset()?.into())
}
pub fn timezone_offset(&self) -> Option<TimezoneOffset> {
self.timestamp.timezone_offset()
}
pub fn to_be_bytes(&self) -> [u8; 18] {
self.timestamp.to_be_bytes()
}
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<DateTime> for GYear {
type Error = DateTimeError;
fn try_from(date_time: DateTime) -> Result<Self, DateTimeError> {
GYear::new(date_time.year(), date_time.timezone_offset())
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<Date> for GYear {
type Error = DateTimeError;
fn try_from(date: Date) -> Result<Self, DateTimeError> {
GYear::new(date.year(), date.timezone_offset())
}
}
impl TryFrom<GYearMonth> for GYear {
type Error = DateTimeError;
fn try_from(year_month: GYearMonth) -> Result<Self, DateTimeError> {
GYear::new(year_month.year(), year_month.timezone_offset())
}
}
impl FromStr for GYear {
type Err = XsdParseError;
fn from_str(input: &str) -> Result<Self, XsdParseError> {
parse_value(g_year_lexical_rep, input)
}
}
impl fmt::Display for GYear {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let year = self.year();
if year < 0 {
write!(f, "-")?;
}
write!(f, "{:04}", year.abs())?;
if let Some(timezone_offset) = self.timezone_offset() {
write!(f, "{}", timezone_offset)?;
}
Ok(())
}
}
/// [XML Schema `gMonthDay` datatype](https://www.w3.org/TR/xmlschema11-2/#gMonthDay) implementation.
#[derive(Eq, PartialEq, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct GMonthDay {
timestamp: Timestamp,
}
impl GMonthDay {
pub(super) fn new(
month: u8,
day: u8,
timezone_offset: Option<TimezoneOffset>,
) -> Result<Self, DateTimeError> {
Ok(Self {
timestamp: Timestamp::new(&DateTimeSevenPropertyModel {
year: None,
month: Some(month),
day: Some(day),
hour: None,
minute: None,
second: None,
timezone_offset,
})?,
})
}
pub fn from_be_bytes(bytes: [u8; 18]) -> Self {
Self {
timestamp: Timestamp::from_be_bytes(bytes),
}
}
pub fn month(&self) -> u8 {
self.timestamp.month()
}
pub fn day(&self) -> u8 {
self.timestamp.day()
}
pub fn timezone(&self) -> Option<DayTimeDuration> {
Some(self.timezone_offset()?.into())
}
pub fn timezone_offset(&self) -> Option<TimezoneOffset> {
self.timestamp.timezone_offset()
}
pub fn to_be_bytes(&self) -> [u8; 18] {
self.timestamp.to_be_bytes()
}
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<DateTime> for GMonthDay {
type Error = DateTimeError;
fn try_from(date_time: DateTime) -> Result<Self, DateTimeError> {
GMonthDay::new(
date_time.month(),
date_time.day(),
date_time.timezone_offset(),
)
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<Date> for GMonthDay {
type Error = DateTimeError;
fn try_from(date: Date) -> Result<Self, DateTimeError> {
GMonthDay::new(date.month(), date.day(), date.timezone_offset())
}
}
impl FromStr for GMonthDay {
type Err = XsdParseError;
fn from_str(input: &str) -> Result<Self, XsdParseError> {
parse_value(g_month_day_lexical_rep, input)
}
}
impl fmt::Display for GMonthDay {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "--{:02}-{:02}", self.month(), self.day())?;
if let Some(timezone_offset) = self.timezone_offset() {
write!(f, "{}", timezone_offset)?;
}
Ok(())
}
}
/// [XML Schema `gMonth` datatype](https://www.w3.org/TR/xmlschema11-2/#gMonth) implementation.
#[derive(Eq, PartialEq, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct GMonth {
timestamp: Timestamp,
}
impl GMonth {
pub(super) fn new(
month: u8,
timezone_offset: Option<TimezoneOffset>,
) -> Result<Self, DateTimeError> {
Ok(Self {
timestamp: Timestamp::new(&DateTimeSevenPropertyModel {
year: None,
month: Some(month),
day: None,
hour: None,
minute: None,
second: None,
timezone_offset,
})?,
})
}
pub fn from_be_bytes(bytes: [u8; 18]) -> Self {
Self {
timestamp: Timestamp::from_be_bytes(bytes),
}
}
pub fn month(&self) -> u8 {
self.timestamp.month()
}
pub fn timezone(&self) -> Option<DayTimeDuration> {
Some(self.timezone_offset()?.into())
}
pub fn timezone_offset(&self) -> Option<TimezoneOffset> {
self.timestamp.timezone_offset()
}
pub fn to_be_bytes(&self) -> [u8; 18] {
self.timestamp.to_be_bytes()
}
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<DateTime> for GMonth {
type Error = DateTimeError;
fn try_from(date_time: DateTime) -> Result<Self, DateTimeError> {
GMonth::new(date_time.month(), date_time.timezone_offset())
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<Date> for GMonth {
type Error = DateTimeError;
fn try_from(date: Date) -> Result<Self, DateTimeError> {
GMonth::new(date.month(), date.timezone_offset())
}
}
impl TryFrom<GYearMonth> for GMonth {
type Error = DateTimeError;
fn try_from(year_month: GYearMonth) -> Result<Self, DateTimeError> {
GMonth::new(year_month.month(), year_month.timezone_offset())
}
}
impl TryFrom<GMonthDay> for GMonth {
type Error = DateTimeError;
fn try_from(month_day: GMonthDay) -> Result<Self, DateTimeError> {
GMonth::new(month_day.month(), month_day.timezone_offset())
}
}
impl FromStr for GMonth {
type Err = XsdParseError;
fn from_str(input: &str) -> Result<Self, XsdParseError> {
parse_value(g_month_lexical_rep, input)
}
}
impl fmt::Display for GMonth {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "--{:02}", self.month())?;
if let Some(timezone_offset) = self.timezone_offset() {
write!(f, "{}", timezone_offset)?;
}
Ok(())
}
}
/// [XML Schema `date` datatype](https://www.w3.org/TR/xmlschema11-2/#date) implementation.
#[derive(Eq, PartialEq, PartialOrd, Debug, Clone, Copy, Hash)]
pub struct GDay {
timestamp: Timestamp,
}
impl GDay {
pub(super) fn new(
day: u8,
timezone_offset: Option<TimezoneOffset>,
) -> Result<Self, DateTimeError> {
Ok(Self {
timestamp: Timestamp::new(&DateTimeSevenPropertyModel {
year: None,
month: None,
day: Some(day),
hour: None,
minute: None,
second: None,
timezone_offset,
})?,
})
}
pub fn from_be_bytes(bytes: [u8; 18]) -> Self {
Self {
timestamp: Timestamp::from_be_bytes(bytes),
}
}
pub fn day(&self) -> u8 {
self.timestamp.day()
}
pub fn timezone(&self) -> Option<DayTimeDuration> {
Some(self.timezone_offset()?.into())
}
pub fn timezone_offset(&self) -> Option<TimezoneOffset> {
self.timestamp.timezone_offset()
}
pub fn to_be_bytes(&self) -> [u8; 18] {
self.timestamp.to_be_bytes()
}
pub fn is_identical_with(&self, other: &Self) -> bool {
self.timestamp.is_identical_with(&other.timestamp)
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<DateTime> for GDay {
type Error = DateTimeError;
fn try_from(date_time: DateTime) -> Result<Self, DateTimeError> {
GDay::new(date_time.day(), date_time.timezone_offset())
}
}
/// Conversion according to [XPath cast rules](https://www.w3.org/TR/xpath-functions/#casting-to-datetimes).
impl TryFrom<Date> for GDay {
type Error = DateTimeError;
fn try_from(date: Date) -> Result<Self, DateTimeError> {
GDay::new(date.day(), date.timezone_offset())
}
}
impl TryFrom<GMonthDay> for GDay {
type Error = DateTimeError;
fn try_from(month_day: GMonthDay) -> Result<Self, DateTimeError> {
GDay::new(month_day.day(), month_day.timezone_offset())
}
}
impl FromStr for GDay {
type Err = XsdParseError;
fn from_str(input: &str) -> Result<Self, XsdParseError> {
parse_value(g_day_lexical_rep, input)
}
}
impl fmt::Display for GDay {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "---{:02}", self.day())?;
if let Some(timezone_offset) = self.timezone_offset() {
write!(f, "{}", timezone_offset)?;
}
Ok(())
}
}
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)] #[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct TimezoneOffset { pub struct TimezoneOffset {
offset: i16, // in minute with respect to UTC offset: i16, // in minute with respect to UTC
@ -826,6 +1335,10 @@ impl Timestamp {
}); });
bytes bytes
} }
pub fn is_identical_with(&self, other: &Self) -> bool {
self.value == other.value && self.timezone_offset == other.timezone_offset
}
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
@ -1178,12 +1691,12 @@ mod tests {
"1899-03-01T00:00:00" "1899-03-01T00:00:00"
); );
/*TODO assert_eq!( assert_eq!(
DateTime::from_str("-1000000000-01-01T00:00:00") DateTime::from_str("-1000000000-01-01T00:00:00")
.unwrap() .unwrap()
.to_string(), .to_string(),
"-1000000000-01-01T00:00:00" "-1000000000-01-01T00:00:00"
);*/ );
assert_eq!( assert_eq!(
DateTime::from_str("-2001-12-31T23:59:59") DateTime::from_str("-2001-12-31T23:59:59")
.unwrap() .unwrap()
@ -1214,6 +1727,27 @@ mod tests {
.to_string(), .to_string(),
"-1899-12-31T23:59:59" "-1899-12-31T23:59:59"
); );
assert_eq!(
GYearMonth::from_str("-1899-12+01:00").unwrap().to_string(),
"-1899-12+01:00"
);
assert_eq!(
GYear::from_str("-1899+01:00").unwrap().to_string(),
"-1899+01:00"
);
assert_eq!(
GMonthDay::from_str("--01-01+01:00").unwrap().to_string(),
"--01-01+01:00"
);
assert_eq!(
GDay::from_str("---01+01:00").unwrap().to_string(),
"---01+01:00"
);
assert_eq!(
GMonth::from_str("--01+01:00").unwrap().to_string(),
"--01+01:00"
);
} }
#[test] #[test]
@ -1306,6 +1840,18 @@ mod tests {
!(Time::from_str("08:00:00+09:00").unwrap() !(Time::from_str("08:00:00+09:00").unwrap()
> Time::from_str("17:00:00-06:00").unwrap()) > Time::from_str("17:00:00-06:00").unwrap())
); );
assert!(
GMonthDay::from_str("--12-12+13:00").unwrap()
< GMonthDay::from_str("--12-12+11:00").unwrap()
);
assert!(GDay::from_str("---15").unwrap() < GDay::from_str("---16").unwrap());
assert!(GDay::from_str("---15-13:00").unwrap() > GDay::from_str("---16+13:00").unwrap());
assert!(GDay::from_str("---15-11:00").unwrap() == GDay::from_str("---16+13:00").unwrap());
assert!(GDay::from_str("---15-13:00")
.unwrap()
.partial_cmp(&GDay::from_str("---16").unwrap())
.is_none());
} }
#[test] #[test]

@ -3,7 +3,7 @@ pub mod decimal;
mod duration; mod duration;
mod parser; mod parser;
pub use self::date_time::{Date, DateTime, Time}; pub use self::date_time::{Date, DateTime, GDay, GMonth, GMonthDay, GYear, GYearMonth, Time};
pub use self::decimal::Decimal; pub use self::decimal::Decimal;
pub use self::duration::{DayTimeDuration, Duration, YearMonthDuration}; pub use self::duration::{DayTimeDuration, Duration, YearMonthDuration};
pub use self::parser::XsdParseError; pub use self::parser::XsdParseError;

@ -12,7 +12,7 @@ use std::str::FromStr;
use super::date_time::DateTimeError; use super::date_time::DateTimeError;
use super::decimal::ParseDecimalError; use super::decimal::ParseDecimalError;
use crate::model::xsd::date_time::TimezoneOffset; use crate::model::xsd::date_time::{GDay, GMonth, GMonthDay, GYear, GYearMonth, TimezoneOffset};
use crate::model::xsd::duration::{DayTimeDuration, YearMonthDuration}; use crate::model::xsd::duration::{DayTimeDuration, YearMonthDuration};
use nom::bytes::streaming::take_while_m_n; use nom::bytes::streaming::take_while_m_n;
use std::error::Error; use std::error::Error;
@ -332,6 +332,59 @@ pub fn date_lexical_rep(input: &str) -> XsdResult<'_, Date> {
)(input) )(input)
} }
// [19] gYearMonthLexicalRep ::= yearFrag '-' monthFrag timezoneFrag?
pub fn g_year_month_lexical_rep(input: &str) -> XsdResult<'_, GYearMonth> {
map_res(
tuple((year_frag, char('-'), month_frag, opt(timezone_frag))),
|(year, _, month, timezone)| GYearMonth::new(year, month, timezone),
)(input)
}
// [20] gYearLexicalRep ::= yearFrag timezoneFrag?
pub fn g_year_lexical_rep(input: &str) -> XsdResult<'_, GYear> {
map_res(
tuple((year_frag, opt(timezone_frag))),
|(year, timezone)| GYear::new(year, timezone),
)(input)
}
// [21] gMonthDayLexicalRep ::= '--' monthFrag '-' dayFrag timezoneFrag? Constraint: Day-of-month Representations
pub fn g_month_day_lexical_rep(input: &str) -> XsdResult<'_, GMonthDay> {
map_res(
tuple((
char('-'),
char('-'),
month_frag,
char('-'),
day_frag,
opt(timezone_frag),
)),
|(_, _, month, _, day, timezone)| GMonthDay::new(month, day, timezone),
)(input)
}
// [22] gDayLexicalRep ::= '---' dayFrag timezoneFrag?
pub fn g_day_lexical_rep(input: &str) -> XsdResult<'_, GDay> {
map_res(
tuple((
char('-'),
char('-'),
char('-'),
day_frag,
opt(timezone_frag),
)),
|(_, _, _, day, timezone)| GDay::new(day, timezone),
)(input)
}
// [23] gMonthLexicalRep ::= '--' monthFrag timezoneFrag?
pub fn g_month_lexical_rep(input: &str) -> XsdResult<'_, GMonth> {
map_res(
tuple((char('-'), char('-'), month_frag, opt(timezone_frag))),
|(_, _, month, timezone)| GMonth::new(month, timezone),
)(input)
}
// [42] yearMonthDurationLexicalRep ::= '-'? 'P' duYearMonthFrag // [42] yearMonthDurationLexicalRep ::= '-'? 'P' duYearMonthFrag
pub fn year_month_duration_lexical_rep(input: &str) -> XsdResult<'_, YearMonthDuration> { pub fn year_month_duration_lexical_rep(input: &str) -> XsdResult<'_, YearMonthDuration> {
map( map(

@ -1,3 +1,4 @@
use crate::model::vocab::{rdf, xsd};
use crate::model::xsd::*; use crate::model::xsd::*;
use crate::model::Triple; use crate::model::Triple;
use crate::model::{BlankNode, LiteralRef, NamedNodeRef}; use crate::model::{BlankNode, LiteralRef, NamedNodeRef};
@ -1281,49 +1282,66 @@ where
} }
} }
PlanExpression::Year(e) => match self.eval_expression(e, tuple)? { PlanExpression::Year(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::DateLiteral(date) => Some(date.year().into()),
EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.year().into()), EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.year().into()),
EncodedTerm::DateLiteral(date) => Some(date.year().into()),
EncodedTerm::GYearMonthLiteral(year_month) => Some(year_month.year().into()),
EncodedTerm::GYearLiteral(year) => Some(year.year().into()),
_ => None, _ => None,
}, },
PlanExpression::Month(e) => match self.eval_expression(e, tuple)? { PlanExpression::Month(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::DateLiteral(date) => Some(date.year().into()),
EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.month().into()), EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.month().into()),
EncodedTerm::DateLiteral(date) => Some(date.year().into()),
EncodedTerm::GYearMonthLiteral(year_month) => Some(year_month.month().into()),
EncodedTerm::GMonthDayLiteral(month_day) => Some(month_day.month().into()),
EncodedTerm::GMonthLiteral(month) => Some(month.month().into()),
_ => None, _ => None,
}, },
PlanExpression::Day(e) => match self.eval_expression(e, tuple)? { PlanExpression::Day(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::DateLiteral(date) => Some(date.year().into()),
EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.day().into()), EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.day().into()),
EncodedTerm::DateLiteral(date) => Some(date.year().into()),
EncodedTerm::GMonthDayLiteral(month_day) => Some(month_day.day().into()),
EncodedTerm::GDayLiteral(day) => Some(day.day().into()),
_ => None, _ => None,
}, },
PlanExpression::Hours(e) => match self.eval_expression(e, tuple)? { PlanExpression::Hours(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::TimeLiteral(time) => Some(time.hour().into()),
EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.hour().into()), EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.hour().into()),
EncodedTerm::TimeLiteral(time) => Some(time.hour().into()),
_ => None, _ => None,
}, },
PlanExpression::Minutes(e) => match self.eval_expression(e, tuple)? { PlanExpression::Minutes(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::TimeLiteral(time) => Some(time.minute().into()),
EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.minute().into()), EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.minute().into()),
EncodedTerm::TimeLiteral(time) => Some(time.minute().into()),
_ => None, _ => None,
}, },
PlanExpression::Seconds(e) => match self.eval_expression(e, tuple)? { PlanExpression::Seconds(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::TimeLiteral(time) => Some(time.second().into()),
EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.second().into()), EncodedTerm::DateTimeLiteral(date_time) => Some(date_time.second().into()),
EncodedTerm::TimeLiteral(time) => Some(time.second().into()),
_ => None, _ => None,
}, },
PlanExpression::Timezone(e) => Some( PlanExpression::Timezone(e) => Some(
match self.eval_expression(e, tuple)? { match self.eval_expression(e, tuple)? {
EncodedTerm::DateLiteral(date) => date.timezone(),
EncodedTerm::TimeLiteral(time) => time.timezone(),
EncodedTerm::DateTimeLiteral(date_time) => date_time.timezone(), EncodedTerm::DateTimeLiteral(date_time) => date_time.timezone(),
EncodedTerm::TimeLiteral(time) => time.timezone(),
EncodedTerm::DateLiteral(date) => date.timezone(),
EncodedTerm::GYearMonthLiteral(year_month) => year_month.timezone(),
EncodedTerm::GYearLiteral(year) => year.timezone(),
EncodedTerm::GMonthDayLiteral(month_day) => month_day.timezone(),
EncodedTerm::GDayLiteral(day) => day.timezone(),
EncodedTerm::GMonthLiteral(month) => month.timezone(),
_ => None, _ => None,
}? }?
.into(), .into(),
), ),
PlanExpression::Tz(e) => { PlanExpression::Tz(e) => {
let timezone_offset = match self.eval_expression(e, tuple)? { let timezone_offset = match self.eval_expression(e, tuple)? {
EncodedTerm::DateLiteral(date) => date.timezone_offset(),
EncodedTerm::TimeLiteral(time) => time.timezone_offset(),
EncodedTerm::DateTimeLiteral(date_time) => date_time.timezone_offset(), EncodedTerm::DateTimeLiteral(date_time) => date_time.timezone_offset(),
EncodedTerm::TimeLiteral(time) => time.timezone_offset(),
EncodedTerm::DateLiteral(date) => date.timezone_offset(),
EncodedTerm::GYearMonthLiteral(year_month) => year_month.timezone_offset(),
EncodedTerm::GYearLiteral(year) => year.timezone_offset(),
EncodedTerm::GMonthDayLiteral(month_day) => month_day.timezone_offset(),
EncodedTerm::GDayLiteral(day) => day.timezone_offset(),
EncodedTerm::GMonthLiteral(month) => month.timezone_offset(),
_ => return None, _ => return None,
}; };
match timezone_offset { match timezone_offset {
@ -1589,9 +1607,14 @@ where
EncodedTerm::DoubleLiteral(value) => self.build_string_id(&value.to_string()), EncodedTerm::DoubleLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::IntegerLiteral(value) => self.build_string_id(&value.to_string()), EncodedTerm::IntegerLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::DecimalLiteral(value) => self.build_string_id(&value.to_string()), EncodedTerm::DecimalLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::DateLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::TimeLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::DateTimeLiteral(value) => self.build_string_id(&value.to_string()), EncodedTerm::DateTimeLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::TimeLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::DateLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::GYearMonthLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::GYearLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::GMonthDayLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::GDayLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::GMonthLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::DurationLiteral(value) => self.build_string_id(&value.to_string()), EncodedTerm::DurationLiteral(value) => self.build_string_id(&value.to_string()),
EncodedTerm::YearMonthDurationLiteral(value) => { EncodedTerm::YearMonthDurationLiteral(value) => {
self.build_string_id(&value.to_string()) self.build_string_id(&value.to_string())
@ -1928,8 +1951,8 @@ where
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None, EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false), _ => Some(false),
}, },
EncodedTerm::DateLiteral(a) => match b { EncodedTerm::DateTimeLiteral(a) => match b {
EncodedTerm::DateLiteral(b) => Some(a == b), EncodedTerm::DateTimeLiteral(b) => Some(a == b),
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None, EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false), _ => Some(false),
}, },
@ -1938,8 +1961,33 @@ where
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None, EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false), _ => Some(false),
}, },
EncodedTerm::DateTimeLiteral(a) => match b { EncodedTerm::DateLiteral(a) => match b {
EncodedTerm::DateTimeLiteral(b) => Some(a == b), EncodedTerm::DateLiteral(b) => Some(a == b),
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::GYearMonthLiteral(a) => match b {
EncodedTerm::GYearMonthLiteral(b) => Some(a == b),
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::GYearLiteral(a) => match b {
EncodedTerm::GYearLiteral(b) => Some(a == b),
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::GMonthDayLiteral(a) => match b {
EncodedTerm::GMonthDayLiteral(b) => Some(a == b),
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::GDayLiteral(a) => match b {
EncodedTerm::GDayLiteral(b) => Some(a == b),
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::GMonthLiteral(a) => match b {
EncodedTerm::GMonthLiteral(b) => Some(a == b),
EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None, EncodedTerm::SmallTypedLiteral { .. } | EncodedTerm::BigTypedLiteral { .. } => None,
_ => Some(false), _ => Some(false),
}, },
@ -2062,8 +2110,8 @@ where
EncodedTerm::DecimalLiteral(ref b) => a.partial_cmp(b), EncodedTerm::DecimalLiteral(ref b) => a.partial_cmp(b),
_ => None, _ => None,
}, },
EncodedTerm::DateLiteral(a) => { EncodedTerm::DateTimeLiteral(a) => {
if let EncodedTerm::DateLiteral(ref b) = b { if let EncodedTerm::DateTimeLiteral(ref b) = b {
a.partial_cmp(b) a.partial_cmp(b)
} else { } else {
None None
@ -2076,8 +2124,43 @@ where
None None
} }
} }
EncodedTerm::DateTimeLiteral(a) => { EncodedTerm::DateLiteral(a) => {
if let EncodedTerm::DateTimeLiteral(ref b) = b { if let EncodedTerm::DateLiteral(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::GYearMonthLiteral(a) => {
if let EncodedTerm::GYearMonthLiteral(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::GYearLiteral(a) => {
if let EncodedTerm::GYearLiteral(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::GMonthDayLiteral(a) => {
if let EncodedTerm::GMonthDayLiteral(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::GDayLiteral(a) => {
if let EncodedTerm::GDayLiteral(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::GMonthLiteral(a) => {
if let EncodedTerm::GMonthLiteral(ref b) = b {
a.partial_cmp(b) a.partial_cmp(b)
} else { } else {
None None
@ -2141,50 +2224,37 @@ where
| EncodedTerm::NumericalBlankNode { .. } | EncodedTerm::NumericalBlankNode { .. }
| EncodedTerm::DefaultGraph => None, | EncodedTerm::DefaultGraph => None,
EncodedTerm::SmallStringLiteral(_) | EncodedTerm::BigStringLiteral { .. } => { EncodedTerm::SmallStringLiteral(_) | EncodedTerm::BigStringLiteral { .. } => {
self.build_named_node("http://www.w3.org/2001/XMLSchema#string") self.build_named_node(xsd::STRING.as_str())
} }
EncodedTerm::SmallSmallLangStringLiteral { .. } EncodedTerm::SmallSmallLangStringLiteral { .. }
| EncodedTerm::SmallBigLangStringLiteral { .. } | EncodedTerm::SmallBigLangStringLiteral { .. }
| EncodedTerm::BigSmallLangStringLiteral { .. } | EncodedTerm::BigSmallLangStringLiteral { .. }
| EncodedTerm::BigBigLangStringLiteral { .. } => { | EncodedTerm::BigBigLangStringLiteral { .. } => {
self.build_named_node("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString") self.build_named_node(rdf::LANG_STRING.as_str())
} }
EncodedTerm::SmallTypedLiteral { datatype_id, .. } EncodedTerm::SmallTypedLiteral { datatype_id, .. }
| EncodedTerm::BigTypedLiteral { datatype_id, .. } => Some(EncodedTerm::NamedNode { | EncodedTerm::BigTypedLiteral { datatype_id, .. } => Some(EncodedTerm::NamedNode {
iri_id: datatype_id, iri_id: datatype_id,
}), }),
EncodedTerm::BooleanLiteral(..) => { EncodedTerm::BooleanLiteral(..) => self.build_named_node(xsd::BOOLEAN.as_str()),
self.build_named_node("http://www.w3.org/2001/XMLSchema#boolean") EncodedTerm::FloatLiteral(..) => self.build_named_node(xsd::FLOAT.as_str()),
} EncodedTerm::DoubleLiteral(..) => self.build_named_node(xsd::DOUBLE.as_str()),
EncodedTerm::FloatLiteral(..) => { EncodedTerm::IntegerLiteral(..) => self.build_named_node(xsd::INTEGER.as_str()),
self.build_named_node("http://www.w3.org/2001/XMLSchema#float") EncodedTerm::DecimalLiteral(..) => self.build_named_node(xsd::DECIMAL.as_str()),
} EncodedTerm::DateTimeLiteral(..) => self.build_named_node(xsd::DATE_TIME.as_str()),
EncodedTerm::DoubleLiteral(..) => { EncodedTerm::TimeLiteral(..) => self.build_named_node(xsd::TIME.as_str()),
self.build_named_node("http://www.w3.org/2001/XMLSchema#double") EncodedTerm::DateLiteral(..) => self.build_named_node(xsd::DATE.as_str()),
} EncodedTerm::GYearMonthLiteral(..) => self.build_named_node(xsd::G_YEAR_MONTH.as_str()),
EncodedTerm::IntegerLiteral(..) => { EncodedTerm::GYearLiteral(..) => self.build_named_node(xsd::G_YEAR.as_str()),
self.build_named_node("http://www.w3.org/2001/XMLSchema#integer") EncodedTerm::GMonthDayLiteral(..) => self.build_named_node(xsd::G_MONTH_DAY.as_str()),
} EncodedTerm::GDayLiteral(..) => self.build_named_node(xsd::G_DAY.as_str()),
EncodedTerm::DecimalLiteral(..) => { EncodedTerm::GMonthLiteral(..) => self.build_named_node(xsd::G_MONTH.as_str()),
self.build_named_node("http://www.w3.org/2001/XMLSchema#decimal") EncodedTerm::DurationLiteral(..) => self.build_named_node(xsd::DURATION.as_str()),
}
EncodedTerm::DateLiteral(..) => {
self.build_named_node("http://www.w3.org/2001/XMLSchema#date")
}
EncodedTerm::TimeLiteral(..) => {
self.build_named_node("http://www.w3.org/2001/XMLSchema#time")
}
EncodedTerm::DateTimeLiteral(..) => {
self.build_named_node("http://www.w3.org/2001/XMLSchema#dateTime")
}
EncodedTerm::DurationLiteral(..) => {
self.build_named_node("http://www.w3.org/2001/XMLSchema#duration")
}
EncodedTerm::YearMonthDurationLiteral(..) => { EncodedTerm::YearMonthDurationLiteral(..) => {
self.build_named_node("http://www.w3.org/2001/XMLSchema#yearMonthDuration") self.build_named_node(xsd::YEAR_MONTH_DURATION.as_str())
} }
EncodedTerm::DayTimeDurationLiteral(..) => { EncodedTerm::DayTimeDurationLiteral(..) => {
self.build_named_node("http://www.w3.org/2001/XMLSchema#dayTimeDuration") self.build_named_node(xsd::DAY_TIME_DURATION.as_str())
} }
} }
} }

@ -39,11 +39,16 @@ const TYPE_DOUBLE_LITERAL: u8 = 31;
const TYPE_INTEGER_LITERAL: u8 = 32; const TYPE_INTEGER_LITERAL: u8 = 32;
const TYPE_DECIMAL_LITERAL: u8 = 33; const TYPE_DECIMAL_LITERAL: u8 = 33;
const TYPE_DATE_TIME_LITERAL: u8 = 34; const TYPE_DATE_TIME_LITERAL: u8 = 34;
const TYPE_DATE_LITERAL: u8 = 35; const TYPE_TIME_LITERAL: u8 = 35;
const TYPE_TIME_LITERAL: u8 = 36; const TYPE_DATE_LITERAL: u8 = 36;
const TYPE_DURATION_LITERAL: u8 = 37; const TYPE_G_YEAR_MONTH_LITERAL: u8 = 37;
const TYPE_YEAR_MONTH_DURATION_LITERAL: u8 = 38; const TYPE_G_YEAR_LITERAL: u8 = 38;
const TYPE_DAY_TIME_DURATION_LITERAL: u8 = 39; const TYPE_G_MONTH_DAY_LITERAL: u8 = 39;
const TYPE_G_DAY_LITERAL: u8 = 40;
const TYPE_G_MONTH_LITERAL: u8 = 41;
const TYPE_DURATION_LITERAL: u8 = 42;
const TYPE_YEAR_MONTH_DURATION_LITERAL: u8 = 43;
const TYPE_DAY_TIME_DURATION_LITERAL: u8 = 44;
#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
#[repr(transparent)] #[repr(transparent)]
@ -354,23 +359,52 @@ impl<R: Read> TermReader for R {
self.read_exact(&mut buffer)?; self.read_exact(&mut buffer)?;
Ok(EncodedTerm::DecimalLiteral(Decimal::from_be_bytes(buffer))) Ok(EncodedTerm::DecimalLiteral(Decimal::from_be_bytes(buffer)))
} }
TYPE_DATE_LITERAL => { TYPE_DATE_TIME_LITERAL => {
let mut buffer = [0; 18]; let mut buffer = [0; 18];
self.read_exact(&mut buffer)?; self.read_exact(&mut buffer)?;
Ok(EncodedTerm::DateLiteral(Date::from_be_bytes(buffer))) Ok(EncodedTerm::DateTimeLiteral(DateTime::from_be_bytes(
buffer,
)))
} }
TYPE_TIME_LITERAL => { TYPE_TIME_LITERAL => {
let mut buffer = [0; 18]; let mut buffer = [0; 18];
self.read_exact(&mut buffer)?; self.read_exact(&mut buffer)?;
Ok(EncodedTerm::TimeLiteral(Time::from_be_bytes(buffer))) Ok(EncodedTerm::TimeLiteral(Time::from_be_bytes(buffer)))
} }
TYPE_DATE_TIME_LITERAL => { TYPE_DATE_LITERAL => {
let mut buffer = [0; 18]; let mut buffer = [0; 18];
self.read_exact(&mut buffer)?; self.read_exact(&mut buffer)?;
Ok(EncodedTerm::DateTimeLiteral(DateTime::from_be_bytes( Ok(EncodedTerm::DateLiteral(Date::from_be_bytes(buffer)))
}
TYPE_G_YEAR_MONTH_LITERAL => {
let mut buffer = [0; 18];
self.read_exact(&mut buffer)?;
Ok(EncodedTerm::GYearMonthLiteral(GYearMonth::from_be_bytes(
buffer, buffer,
))) )))
} }
TYPE_G_YEAR_LITERAL => {
let mut buffer = [0; 18];
self.read_exact(&mut buffer)?;
Ok(EncodedTerm::GYearLiteral(GYear::from_be_bytes(buffer)))
}
TYPE_G_MONTH_DAY_LITERAL => {
let mut buffer = [0; 18];
self.read_exact(&mut buffer)?;
Ok(EncodedTerm::GMonthDayLiteral(GMonthDay::from_be_bytes(
buffer,
)))
}
TYPE_G_DAY_LITERAL => {
let mut buffer = [0; 18];
self.read_exact(&mut buffer)?;
Ok(EncodedTerm::GDayLiteral(GDay::from_be_bytes(buffer)))
}
TYPE_G_MONTH_LITERAL => {
let mut buffer = [0; 18];
self.read_exact(&mut buffer)?;
Ok(EncodedTerm::GMonthLiteral(GMonth::from_be_bytes(buffer)))
}
TYPE_DURATION_LITERAL => { TYPE_DURATION_LITERAL => {
let mut buffer = [0; 24]; let mut buffer = [0; 24];
self.read_exact(&mut buffer)?; self.read_exact(&mut buffer)?;
@ -573,22 +607,42 @@ pub fn write_term(sink: &mut Vec<u8>, term: EncodedTerm) {
sink.push(TYPE_DECIMAL_LITERAL); sink.push(TYPE_DECIMAL_LITERAL);
sink.extend_from_slice(&value.to_be_bytes()) sink.extend_from_slice(&value.to_be_bytes())
} }
EncodedTerm::DateLiteral(value) => { EncodedTerm::DateTimeLiteral(value) => {
sink.push(TYPE_DATE_LITERAL); sink.push(TYPE_DATE_TIME_LITERAL);
sink.extend_from_slice(&value.to_be_bytes()) sink.extend_from_slice(&value.to_be_bytes())
} }
EncodedTerm::TimeLiteral(value) => { EncodedTerm::TimeLiteral(value) => {
sink.push(TYPE_TIME_LITERAL); sink.push(TYPE_TIME_LITERAL);
sink.extend_from_slice(&value.to_be_bytes()) sink.extend_from_slice(&value.to_be_bytes())
} }
EncodedTerm::DateTimeLiteral(value) => {
sink.push(TYPE_DATE_TIME_LITERAL);
sink.extend_from_slice(&value.to_be_bytes())
}
EncodedTerm::DurationLiteral(value) => { EncodedTerm::DurationLiteral(value) => {
sink.push(TYPE_DURATION_LITERAL); sink.push(TYPE_DURATION_LITERAL);
sink.extend_from_slice(&value.to_be_bytes()) sink.extend_from_slice(&value.to_be_bytes())
} }
EncodedTerm::DateLiteral(value) => {
sink.push(TYPE_DATE_LITERAL);
sink.extend_from_slice(&value.to_be_bytes())
}
EncodedTerm::GYearMonthLiteral(value) => {
sink.push(TYPE_G_YEAR_MONTH_LITERAL);
sink.extend_from_slice(&value.to_be_bytes())
}
EncodedTerm::GYearLiteral(value) => {
sink.push(TYPE_G_YEAR_LITERAL);
sink.extend_from_slice(&value.to_be_bytes())
}
EncodedTerm::GMonthDayLiteral(value) => {
sink.push(TYPE_G_MONTH_DAY_LITERAL);
sink.extend_from_slice(&value.to_be_bytes())
}
EncodedTerm::GDayLiteral(value) => {
sink.push(TYPE_G_DAY_LITERAL);
sink.extend_from_slice(&value.to_be_bytes())
}
EncodedTerm::GMonthLiteral(value) => {
sink.push(TYPE_G_MONTH_LITERAL);
sink.extend_from_slice(&value.to_be_bytes())
}
EncodedTerm::YearMonthDurationLiteral(value) => { EncodedTerm::YearMonthDurationLiteral(value) => {
sink.push(TYPE_YEAR_MONTH_DURATION_LITERAL); sink.push(TYPE_YEAR_MONTH_DURATION_LITERAL);
sink.extend_from_slice(&value.to_be_bytes()) sink.extend_from_slice(&value.to_be_bytes())
@ -686,7 +740,14 @@ mod test {
Literal::new_typed_literal("2020-01-01T01:01:01Z", xsd::DATE_TIME).into(), Literal::new_typed_literal("2020-01-01T01:01:01Z", xsd::DATE_TIME).into(),
Literal::new_typed_literal("2020-01-01", xsd::DATE).into(), Literal::new_typed_literal("2020-01-01", xsd::DATE).into(),
Literal::new_typed_literal("01:01:01Z", xsd::TIME).into(), Literal::new_typed_literal("01:01:01Z", xsd::TIME).into(),
Literal::new_typed_literal("2020-01", xsd::G_YEAR_MONTH).into(),
Literal::new_typed_literal("2020", xsd::G_YEAR).into(),
Literal::new_typed_literal("--01-01", xsd::G_MONTH_DAY).into(),
Literal::new_typed_literal("--01", xsd::G_MONTH).into(),
Literal::new_typed_literal("---01", xsd::G_DAY).into(),
Literal::new_typed_literal("PT1S", xsd::DURATION).into(), Literal::new_typed_literal("PT1S", xsd::DURATION).into(),
Literal::new_typed_literal("PT1S", xsd::DAY_TIME_DURATION).into(),
Literal::new_typed_literal("P1Y", xsd::YEAR_MONTH_DURATION).into(),
Literal::new_typed_literal("-foo", NamedNode::new_unchecked("http://foo.com")).into(), Literal::new_typed_literal("-foo", NamedNode::new_unchecked("http://foo.com")).into(),
Literal::new_typed_literal( Literal::new_typed_literal(
"-foo-thisisaverybigtypedliteralwiththefoodatatype", "-foo-thisisaverybigtypedliteralwiththefoodatatype",

@ -63,9 +63,14 @@ pub enum EncodedTerm<I: StrId> {
DoubleLiteral(f64), DoubleLiteral(f64),
IntegerLiteral(i64), IntegerLiteral(i64),
DecimalLiteral(Decimal), DecimalLiteral(Decimal),
DateLiteral(Date),
TimeLiteral(Time),
DateTimeLiteral(DateTime), DateTimeLiteral(DateTime),
TimeLiteral(Time),
DateLiteral(Date),
GYearMonthLiteral(GYearMonth),
GYearLiteral(GYear),
GMonthDayLiteral(GMonthDay),
GDayLiteral(GDay),
GMonthLiteral(GMonth),
DurationLiteral(Duration), DurationLiteral(Duration),
YearMonthDurationLiteral(YearMonthDuration), YearMonthDurationLiteral(YearMonthDuration),
DayTimeDurationLiteral(DayTimeDuration), DayTimeDurationLiteral(DayTimeDuration),
@ -171,9 +176,14 @@ impl<I: StrId> PartialEq for EncodedTerm<I> {
} }
(Self::IntegerLiteral(a), Self::IntegerLiteral(b)) => a == b, (Self::IntegerLiteral(a), Self::IntegerLiteral(b)) => a == b,
(Self::DecimalLiteral(a), Self::DecimalLiteral(b)) => a == b, (Self::DecimalLiteral(a), Self::DecimalLiteral(b)) => a == b,
(Self::DateLiteral(a), Self::DateLiteral(b)) => a == b, (Self::DateTimeLiteral(a), Self::DateTimeLiteral(b)) => a.is_identical_with(b),
(Self::TimeLiteral(a), Self::TimeLiteral(b)) => a == b, (Self::TimeLiteral(a), Self::TimeLiteral(b)) => a.is_identical_with(b),
(Self::DateTimeLiteral(a), Self::DateTimeLiteral(b)) => a == b, (Self::DateLiteral(a), Self::DateLiteral(b)) => a.is_identical_with(b),
(Self::GYearMonthLiteral(a), Self::GYearMonthLiteral(b)) => a.is_identical_with(b),
(Self::GYearLiteral(a), Self::GYearLiteral(b)) => a.is_identical_with(b),
(Self::GMonthDayLiteral(a), Self::GMonthDayLiteral(b)) => a.is_identical_with(b),
(Self::GMonthLiteral(a), Self::GMonthLiteral(b)) => a.is_identical_with(b),
(Self::GDayLiteral(a), Self::GDayLiteral(b)) => a.is_identical_with(b),
(Self::DurationLiteral(a), Self::DurationLiteral(b)) => a == b, (Self::DurationLiteral(a), Self::DurationLiteral(b)) => a == b,
(Self::YearMonthDurationLiteral(a), Self::YearMonthDurationLiteral(b)) => a == b, (Self::YearMonthDurationLiteral(a), Self::YearMonthDurationLiteral(b)) => a == b,
(Self::DayTimeDurationLiteral(a), Self::DayTimeDurationLiteral(b)) => a == b, (Self::DayTimeDurationLiteral(a), Self::DayTimeDurationLiteral(b)) => a == b,
@ -229,9 +239,14 @@ impl<I: StrId> Hash for EncodedTerm<I> {
Self::DoubleLiteral(value) => state.write(&value.to_ne_bytes()), Self::DoubleLiteral(value) => state.write(&value.to_ne_bytes()),
Self::IntegerLiteral(value) => value.hash(state), Self::IntegerLiteral(value) => value.hash(state),
Self::DecimalLiteral(value) => value.hash(state), Self::DecimalLiteral(value) => value.hash(state),
Self::DateLiteral(value) => value.hash(state),
Self::TimeLiteral(value) => value.hash(state),
Self::DateTimeLiteral(value) => value.hash(state), Self::DateTimeLiteral(value) => value.hash(state),
Self::TimeLiteral(value) => value.hash(state),
Self::DateLiteral(value) => value.hash(state),
Self::GYearMonthLiteral(value) => value.hash(state),
Self::GYearLiteral(value) => value.hash(state),
Self::GMonthDayLiteral(value) => value.hash(state),
Self::GDayLiteral(value) => value.hash(state),
Self::GMonthLiteral(value) => value.hash(state),
Self::DurationLiteral(value) => value.hash(state), Self::DurationLiteral(value) => value.hash(state),
Self::YearMonthDurationLiteral(value) => value.hash(state), Self::YearMonthDurationLiteral(value) => value.hash(state),
Self::DayTimeDurationLiteral(value) => value.hash(state), Self::DayTimeDurationLiteral(value) => value.hash(state),
@ -271,9 +286,14 @@ impl<I: StrId> EncodedTerm<I> {
| Self::DoubleLiteral(_) | Self::DoubleLiteral(_)
| Self::IntegerLiteral(_) | Self::IntegerLiteral(_)
| Self::DecimalLiteral(_) | Self::DecimalLiteral(_)
| Self::DateLiteral(_)
| Self::TimeLiteral(_)
| Self::DateTimeLiteral(_) | Self::DateTimeLiteral(_)
| Self::TimeLiteral(_)
| Self::DateLiteral(_)
| Self::GYearMonthLiteral(_)
| Self::GYearLiteral(_)
| Self::GMonthDayLiteral(_)
| Self::GDayLiteral(_)
| Self::GMonthLiteral(_)
| Self::DurationLiteral(_) | Self::DurationLiteral(_)
| Self::YearMonthDurationLiteral(_) | Self::YearMonthDurationLiteral(_)
| Self::DayTimeDurationLiteral(_) => true, | Self::DayTimeDurationLiteral(_) => true,
@ -338,9 +358,14 @@ impl<I: StrId> EncodedTerm<I> {
Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value), Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value),
Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value), Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value),
Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value), Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value),
Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value),
Self::DateLiteral(value) => EncodedTerm::DateLiteral(value), Self::DateLiteral(value) => EncodedTerm::DateLiteral(value),
Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value), Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value),
Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value), Self::GYearMonthLiteral(value) => EncodedTerm::GYearMonthLiteral(value),
Self::GYearLiteral(value) => EncodedTerm::GYearLiteral(value),
Self::GMonthDayLiteral(value) => EncodedTerm::GMonthDayLiteral(value),
Self::GDayLiteral(value) => EncodedTerm::GDayLiteral(value),
Self::GMonthLiteral(value) => EncodedTerm::GMonthLiteral(value),
Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value), Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value),
Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value), Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value),
Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value), Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value),
@ -400,9 +425,14 @@ impl<I: StrId> EncodedTerm<I> {
Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value), Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value),
Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value), Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value),
Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value), Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value),
Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value),
Self::DateLiteral(value) => EncodedTerm::DateLiteral(value), Self::DateLiteral(value) => EncodedTerm::DateLiteral(value),
Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value), Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value),
Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value), Self::GYearMonthLiteral(value) => EncodedTerm::GYearMonthLiteral(value),
Self::GYearLiteral(value) => EncodedTerm::GYearLiteral(value),
Self::GMonthDayLiteral(value) => EncodedTerm::GMonthDayLiteral(value),
Self::GDayLiteral(value) => EncodedTerm::GDayLiteral(value),
Self::GMonthLiteral(value) => EncodedTerm::GMonthLiteral(value),
Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value), Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value),
Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value), Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value),
Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value), Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value),
@ -457,9 +487,9 @@ impl<I: StrId> From<Decimal> for EncodedTerm<I> {
} }
} }
impl<I: StrId> From<Date> for EncodedTerm<I> { impl<I: StrId> From<DateTime> for EncodedTerm<I> {
fn from(value: Date) -> Self { fn from(value: DateTime) -> Self {
Self::DateLiteral(value) Self::DateTimeLiteral(value)
} }
} }
@ -469,9 +499,9 @@ impl<I: StrId> From<Time> for EncodedTerm<I> {
} }
} }
impl<I: StrId> From<DateTime> for EncodedTerm<I> { impl<I: StrId> From<Date> for EncodedTerm<I> {
fn from(value: DateTime) -> Self { fn from(value: Date) -> Self {
Self::DateTimeLiteral(value) Self::DateLiteral(value)
} }
} }
@ -660,10 +690,15 @@ pub(crate) trait ReadEncoder: WithStoreError {
| "http://www.w3.org/2001/XMLSchema#nonPositiveInteger" | "http://www.w3.org/2001/XMLSchema#nonPositiveInteger"
| "http://www.w3.org/2001/XMLSchema#nonNegativeInteger" => parse_integer_str(value), | "http://www.w3.org/2001/XMLSchema#nonNegativeInteger" => parse_integer_str(value),
"http://www.w3.org/2001/XMLSchema#decimal" => parse_decimal_str(value), "http://www.w3.org/2001/XMLSchema#decimal" => parse_decimal_str(value),
"http://www.w3.org/2001/XMLSchema#date" => parse_date_str(value),
"http://www.w3.org/2001/XMLSchema#time" => parse_time_str(value),
"http://www.w3.org/2001/XMLSchema#dateTime" "http://www.w3.org/2001/XMLSchema#dateTime"
| "http://www.w3.org/2001/XMLSchema#dateTimeStamp" => parse_date_time_str(value), | "http://www.w3.org/2001/XMLSchema#dateTimeStamp" => parse_date_time_str(value),
"http://www.w3.org/2001/XMLSchema#time" => parse_time_str(value),
"http://www.w3.org/2001/XMLSchema#date" => parse_date_str(value),
"http://www.w3.org/2001/XMLSchema#gYearMonth" => parse_g_year_month_str(value),
"http://www.w3.org/2001/XMLSchema#gYear" => parse_g_year_str(value),
"http://www.w3.org/2001/XMLSchema#gMonthDay" => parse_g_month_day_str(value),
"http://www.w3.org/2001/XMLSchema#gDay" => parse_g_day_str(value),
"http://www.w3.org/2001/XMLSchema#gMonth" => parse_g_month_str(value),
"http://www.w3.org/2001/XMLSchema#duration" => parse_duration_str(value), "http://www.w3.org/2001/XMLSchema#duration" => parse_duration_str(value),
"http://www.w3.org/2001/XMLSchema#yearMonthDuration" => { "http://www.w3.org/2001/XMLSchema#yearMonthDuration" => {
parse_year_month_duration_str(value) parse_year_month_duration_str(value)
@ -949,12 +984,17 @@ pub(crate) trait WriteEncoder: WithStoreError {
parse_integer_str(value) parse_integer_str(value)
} }
"http://www.w3.org/2001/XMLSchema#decimal" => parse_decimal_str(value), "http://www.w3.org/2001/XMLSchema#decimal" => parse_decimal_str(value),
"http://www.w3.org/2001/XMLSchema#date" => parse_date_str(value),
"http://www.w3.org/2001/XMLSchema#time" => parse_time_str(value),
"http://www.w3.org/2001/XMLSchema#dateTime" "http://www.w3.org/2001/XMLSchema#dateTime"
| "http://www.w3.org/2001/XMLSchema#dateTimeStamp" => { | "http://www.w3.org/2001/XMLSchema#dateTimeStamp" => {
parse_date_time_str(value) parse_date_time_str(value)
} }
"http://www.w3.org/2001/XMLSchema#time" => parse_time_str(value),
"http://www.w3.org/2001/XMLSchema#date" => parse_date_str(value),
"http://www.w3.org/2001/XMLSchema#gYearMonth" => parse_g_year_month_str(value),
"http://www.w3.org/2001/XMLSchema#gYear" => parse_g_year_str(value),
"http://www.w3.org/2001/XMLSchema#gMonthDay" => parse_g_month_day_str(value),
"http://www.w3.org/2001/XMLSchema#gDay" => parse_g_day_str(value),
"http://www.w3.org/2001/XMLSchema#gMonth" => parse_g_month_str(value),
"http://www.w3.org/2001/XMLSchema#duration" => parse_duration_str(value), "http://www.w3.org/2001/XMLSchema#duration" => parse_duration_str(value),
"http://www.w3.org/2001/XMLSchema#yearMonthDuration" => { "http://www.w3.org/2001/XMLSchema#yearMonthDuration" => {
parse_year_month_duration_str(value) parse_year_month_duration_str(value)
@ -1071,16 +1111,36 @@ pub fn parse_decimal_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::DecimalLiteral).ok() value.parse().map(EncodedTerm::DecimalLiteral).ok()
} }
pub fn parse_date_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_date_time_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::DateLiteral).ok() value.parse().map(EncodedTerm::DateTimeLiteral).ok()
} }
pub fn parse_time_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_time_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::TimeLiteral).ok() value.parse().map(EncodedTerm::TimeLiteral).ok()
} }
pub fn parse_date_time_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_date_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::DateTimeLiteral).ok() value.parse().map(EncodedTerm::DateLiteral).ok()
}
pub fn parse_g_year_month_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::GYearMonthLiteral).ok()
}
pub fn parse_g_year_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::GYearLiteral).ok()
}
pub fn parse_g_month_day_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::GMonthDayLiteral).ok()
}
pub fn parse_g_day_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::GDayLiteral).ok()
}
pub fn parse_g_month_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
value.parse().map(EncodedTerm::GMonthLiteral).ok()
} }
pub fn parse_duration_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> { pub fn parse_duration_str<I: StrId>(value: &str) -> Option<EncodedTerm<I>> {
@ -1225,9 +1285,14 @@ impl<S: StrLookup> Decoder for S {
EncodedTerm::DoubleLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::DoubleLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::IntegerLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::IntegerLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::DecimalLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::DecimalLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::DateTimeLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::DateLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::DateLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::TimeLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::TimeLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::DateTimeLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::GYearMonthLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::GYearLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::GMonthDayLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::GDayLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::GMonthLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::DurationLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::DurationLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::YearMonthDurationLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::YearMonthDurationLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::DayTimeDurationLiteral(value) => Ok(Literal::from(value).into()), EncodedTerm::DayTimeDurationLiteral(value) => Ok(Literal::from(value).into()),

Loading…
Cancel
Save