#![allow(clippy::unreadable_literal)] use crate::error::invalid_data_error; use crate::model::xsd::*; use crate::model::*; use crate::sparql::EvaluationError; use rand::random; use rio_api::model as rio; use siphasher::sip128::{Hasher128, SipHasher24}; use std::collections::HashMap; use std::convert::Infallible; use std::error::Error; use std::fmt::Debug; use std::hash::Hash; use std::hash::Hasher; use std::io::Read; use std::mem::size_of; use std::{fmt, io, str}; pub trait StrId: Eq + Debug + Copy + Hash {} pub trait SerializableStrId: StrId { fn len() -> usize; fn from_be_bytes(bytes: &[u8]) -> Self; fn push_be_bytes(&self, buffer: &mut Vec); } #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] #[repr(transparent)] pub struct StrHash { hash: u128, } impl StrHash { pub fn new(value: &str) -> Self { let mut hasher = SipHasher24::new(); hasher.write(value.as_bytes()); Self { hash: hasher.finish128().into(), } } #[inline] pub fn from_be_bytes(bytes: [u8; 16]) -> Self { Self { hash: u128::from_be_bytes(bytes), } } #[inline] pub fn to_be_bytes(&self) -> [u8; 16] { self.hash.to_be_bytes() } } impl StrId for StrHash {} impl SerializableStrId for StrHash { fn len() -> usize { 16 } fn from_be_bytes(bytes: &[u8]) -> Self { let mut hash = [0; 16]; hash.copy_from_slice(bytes); Self { hash: u128::from_be_bytes(hash), } } fn push_be_bytes(&self, buffer: &mut Vec) { buffer.extend_from_slice(&self.to_be_bytes()) } } const TYPE_DEFAULT_GRAPH_ID: u8 = 0; const TYPE_NAMED_NODE_ID: u8 = 1; const TYPE_INLINE_BLANK_NODE_ID: u8 = 2; const TYPE_NAMED_BLANK_NODE_ID: u8 = 3; const TYPE_LANG_STRING_LITERAL_ID: u8 = 4; const TYPE_TYPED_LITERAL_ID: u8 = 5; const TYPE_STRING_LITERAL: u8 = 6; const TYPE_BOOLEAN_LITERAL_TRUE: u8 = 7; const TYPE_BOOLEAN_LITERAL_FALSE: u8 = 8; const TYPE_FLOAT_LITERAL: u8 = 9; const TYPE_DOUBLE_LITERAL: u8 = 10; const TYPE_INTEGER_LITERAL: u8 = 11; const TYPE_DECIMAL_LITERAL: u8 = 12; const TYPE_DATE_TIME_LITERAL: u8 = 13; const TYPE_DATE_LITERAL: u8 = 14; const TYPE_TIME_LITERAL: u8 = 15; const TYPE_DURATION_LITERAL: u8 = 16; const TYPE_YEAR_MONTH_DURATION_LITERAL: u8 = 17; const TYPE_DAY_TIME_DURATION_LITERAL: u8 = 18; #[derive(Debug, Clone, Copy)] pub enum EncodedTerm { DefaultGraph, NamedNode { iri_id: I }, InlineBlankNode { id: u128 }, NamedBlankNode { id_id: I }, StringLiteral { value_id: I }, LangStringLiteral { value_id: I, language_id: I }, TypedLiteral { value_id: I, datatype_id: I }, BooleanLiteral(bool), FloatLiteral(f32), DoubleLiteral(f64), IntegerLiteral(i64), DecimalLiteral(Decimal), DateLiteral(Date), TimeLiteral(Time), DateTimeLiteral(DateTime), DurationLiteral(Duration), YearMonthDurationLiteral(YearMonthDuration), DayTimeDurationLiteral(DayTimeDuration), } impl PartialEq for EncodedTerm { fn eq(&self, other: &Self) -> bool { match (self, other) { (Self::DefaultGraph, Self::DefaultGraph) => true, (Self::NamedNode { iri_id: iri_id_a }, Self::NamedNode { iri_id: iri_id_b }) => { iri_id_a == iri_id_b } (Self::InlineBlankNode { id: id_a }, Self::InlineBlankNode { id: id_b }) => { id_a == id_b } (Self::NamedBlankNode { id_id: id_a }, Self::NamedBlankNode { id_id: id_b }) => { id_a == id_b } ( Self::StringLiteral { value_id: value_id_a, }, Self::StringLiteral { value_id: value_id_b, }, ) => value_id_a == value_id_b, ( Self::LangStringLiteral { value_id: value_id_a, language_id: language_id_a, }, Self::LangStringLiteral { value_id: value_id_b, language_id: language_id_b, }, ) => value_id_a == value_id_b && language_id_a == language_id_b, ( Self::TypedLiteral { value_id: value_id_a, datatype_id: datatype_id_a, }, Self::TypedLiteral { value_id: value_id_b, datatype_id: datatype_id_b, }, ) => value_id_a == value_id_b && datatype_id_a == datatype_id_b, (Self::BooleanLiteral(a), Self::BooleanLiteral(b)) => a == b, (Self::FloatLiteral(a), Self::FloatLiteral(b)) => { if a.is_nan() { b.is_nan() } else { a == b } } (Self::DoubleLiteral(a), Self::DoubleLiteral(b)) => { if a.is_nan() { b.is_nan() } else { a == b } } (Self::IntegerLiteral(a), Self::IntegerLiteral(b)) => a == b, (Self::DecimalLiteral(a), Self::DecimalLiteral(b)) => a == b, (Self::DateLiteral(a), Self::DateLiteral(b)) => a == b, (Self::TimeLiteral(a), Self::TimeLiteral(b)) => a == b, (Self::DateTimeLiteral(a), Self::DateTimeLiteral(b)) => a == b, (Self::DurationLiteral(a), Self::DurationLiteral(b)) => a == b, (Self::YearMonthDurationLiteral(a), Self::YearMonthDurationLiteral(b)) => a == b, (Self::DayTimeDurationLiteral(a), Self::DayTimeDurationLiteral(b)) => a == b, (_, _) => false, } } } impl Eq for EncodedTerm {} impl Hash for EncodedTerm { fn hash(&self, state: &mut H) { match self { Self::NamedNode { iri_id } => iri_id.hash(state), Self::InlineBlankNode { id } => id.hash(state), Self::NamedBlankNode { id_id } => id_id.hash(state), Self::DefaultGraph => (), Self::StringLiteral { value_id } => value_id.hash(state), Self::LangStringLiteral { value_id, language_id, } => { value_id.hash(state); language_id.hash(state); } Self::TypedLiteral { value_id, datatype_id, } => { value_id.hash(state); datatype_id.hash(state); } Self::BooleanLiteral(value) => value.hash(state), Self::FloatLiteral(value) => state.write(&value.to_ne_bytes()), Self::DoubleLiteral(value) => state.write(&value.to_ne_bytes()), Self::IntegerLiteral(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::DurationLiteral(value) => value.hash(state), Self::YearMonthDurationLiteral(value) => value.hash(state), Self::DayTimeDurationLiteral(value) => value.hash(state), } } } impl EncodedTerm { pub fn is_named_node(&self) -> bool { match self { Self::NamedNode { .. } => true, _ => false, } } pub fn is_blank_node(&self) -> bool { match self { Self::InlineBlankNode { .. } | Self::NamedBlankNode { .. } => true, _ => false, } } pub fn is_literal(&self) -> bool { match self { Self::StringLiteral { .. } | Self::LangStringLiteral { .. } | Self::TypedLiteral { .. } | Self::BooleanLiteral(_) | Self::FloatLiteral(_) | Self::DoubleLiteral(_) | Self::IntegerLiteral(_) | Self::DecimalLiteral(_) | Self::DateLiteral(_) | Self::TimeLiteral(_) | Self::DateTimeLiteral(_) | Self::DurationLiteral(_) | Self::YearMonthDurationLiteral(_) | Self::DayTimeDurationLiteral(_) => true, _ => false, } } pub fn is_default_graph(&self) -> bool { *self == EncodedTerm::DefaultGraph } fn type_id(&self) -> u8 { match self { Self::DefaultGraph { .. } => TYPE_DEFAULT_GRAPH_ID, Self::NamedNode { .. } => TYPE_NAMED_NODE_ID, Self::InlineBlankNode { .. } => TYPE_INLINE_BLANK_NODE_ID, Self::NamedBlankNode { .. } => TYPE_NAMED_BLANK_NODE_ID, Self::StringLiteral { .. } => TYPE_STRING_LITERAL, Self::LangStringLiteral { .. } => TYPE_LANG_STRING_LITERAL_ID, Self::TypedLiteral { .. } => TYPE_TYPED_LITERAL_ID, Self::BooleanLiteral(true) => TYPE_BOOLEAN_LITERAL_TRUE, Self::BooleanLiteral(false) => TYPE_BOOLEAN_LITERAL_FALSE, Self::FloatLiteral(_) => TYPE_FLOAT_LITERAL, Self::DoubleLiteral(_) => TYPE_DOUBLE_LITERAL, Self::IntegerLiteral(_) => TYPE_INTEGER_LITERAL, Self::DecimalLiteral(_) => TYPE_DECIMAL_LITERAL, Self::DateLiteral(_) => TYPE_DATE_LITERAL, Self::TimeLiteral(_) => TYPE_TIME_LITERAL, Self::DateTimeLiteral(_) => TYPE_DATE_TIME_LITERAL, Self::DurationLiteral(_) => TYPE_DURATION_LITERAL, Self::YearMonthDurationLiteral(_) => TYPE_YEAR_MONTH_DURATION_LITERAL, Self::DayTimeDurationLiteral(_) => TYPE_DAY_TIME_DURATION_LITERAL, } } pub fn map_id(self, mapping: impl Fn(I) -> J) -> EncodedTerm { match self { Self::DefaultGraph { .. } => EncodedTerm::DefaultGraph, Self::NamedNode { iri_id } => EncodedTerm::NamedNode { iri_id: mapping(iri_id), }, Self::InlineBlankNode { id } => EncodedTerm::InlineBlankNode { id }, Self::NamedBlankNode { id_id } => EncodedTerm::NamedBlankNode { id_id: mapping(id_id), }, Self::StringLiteral { value_id } => EncodedTerm::StringLiteral { value_id: mapping(value_id), }, Self::LangStringLiteral { value_id, language_id, } => EncodedTerm::LangStringLiteral { value_id: mapping(value_id), language_id: mapping(language_id), }, Self::TypedLiteral { value_id, datatype_id, } => EncodedTerm::TypedLiteral { value_id: mapping(value_id), datatype_id: mapping(datatype_id), }, Self::BooleanLiteral(value) => EncodedTerm::BooleanLiteral(value), Self::FloatLiteral(value) => EncodedTerm::FloatLiteral(value), Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value), Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value), Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value), Self::DateLiteral(value) => EncodedTerm::DateLiteral(value), Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value), Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value), Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value), Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value), Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value), } } pub fn try_map_id(self, mapping: impl Fn(I) -> Option) -> Option> { Some(match self { Self::DefaultGraph { .. } => EncodedTerm::DefaultGraph, Self::NamedNode { iri_id } => EncodedTerm::NamedNode { iri_id: mapping(iri_id)?, }, Self::InlineBlankNode { id } => EncodedTerm::InlineBlankNode { id }, Self::NamedBlankNode { id_id } => EncodedTerm::NamedBlankNode { id_id: mapping(id_id)?, }, Self::StringLiteral { value_id } => EncodedTerm::StringLiteral { value_id: mapping(value_id)?, }, Self::LangStringLiteral { value_id, language_id, } => EncodedTerm::LangStringLiteral { value_id: mapping(value_id)?, language_id: mapping(language_id)?, }, Self::TypedLiteral { value_id, datatype_id, } => EncodedTerm::TypedLiteral { value_id: mapping(value_id)?, datatype_id: mapping(datatype_id)?, }, Self::BooleanLiteral(value) => EncodedTerm::BooleanLiteral(value), Self::FloatLiteral(value) => EncodedTerm::FloatLiteral(value), Self::DoubleLiteral(value) => EncodedTerm::DoubleLiteral(value), Self::IntegerLiteral(value) => EncodedTerm::IntegerLiteral(value), Self::DecimalLiteral(value) => EncodedTerm::DecimalLiteral(value), Self::DateLiteral(value) => EncodedTerm::DateLiteral(value), Self::TimeLiteral(value) => EncodedTerm::TimeLiteral(value), Self::DateTimeLiteral(value) => EncodedTerm::DateTimeLiteral(value), Self::DurationLiteral(value) => EncodedTerm::DurationLiteral(value), Self::YearMonthDurationLiteral(value) => EncodedTerm::YearMonthDurationLiteral(value), Self::DayTimeDurationLiteral(value) => EncodedTerm::DayTimeDurationLiteral(value), }) } } impl From for EncodedTerm { fn from(value: bool) -> Self { Self::BooleanLiteral(value) } } impl From for EncodedTerm { fn from(value: i64) -> Self { Self::IntegerLiteral(value) } } impl From for EncodedTerm { fn from(value: i32) -> Self { Self::IntegerLiteral(value.into()) } } impl From for EncodedTerm { fn from(value: u32) -> Self { Self::IntegerLiteral(value.into()) } } impl From for EncodedTerm { fn from(value: u8) -> Self { Self::IntegerLiteral(value.into()) } } impl From for EncodedTerm { fn from(value: f32) -> Self { Self::FloatLiteral(value) } } impl From for EncodedTerm { fn from(value: f64) -> Self { Self::DoubleLiteral(value) } } impl From for EncodedTerm { fn from(value: Decimal) -> Self { Self::DecimalLiteral(value) } } impl From for EncodedTerm { fn from(value: Date) -> Self { Self::DateLiteral(value) } } impl From