Skip to content

Commit

Permalink
340/89 schema tests pass, 4 unimplemented, Started work on exclusions...
Browse files Browse the repository at this point in the history
  • Loading branch information
labra committed Nov 23, 2023
1 parent b11f89c commit 6820deb
Show file tree
Hide file tree
Showing 11 changed files with 492 additions and 141 deletions.
196 changes: 196 additions & 0 deletions shex_ast/src/ast/exclusion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
use std::str::FromStr;
use std::{fmt, result};

use serde::de::{MapAccess, Visitor};
use serde::ser::SerializeMap;
use serde::{de, Deserialize, Serialize, Serializer};
use serde_derive::{Deserialize, Serialize};
use srdf::lang::Lang;

use crate::IriRef;

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum LiteralExclusion {
Literal(String),
LiteralStem(String),
}

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum IriExclusion {
Iri(IriRef),
IriStem(String),
}

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum LanguageExclusion {
Language(Lang),
LanguageStem(String),
}

#[derive(Debug, PartialEq, Clone)]
pub enum Exclusion {
LiteralExclusion(LiteralExclusion),
LanguageExclusion(LanguageExclusion),
IriExclusion(IriExclusion),
}

impl Serialize for Exclusion {
fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Exclusion::IriExclusion(iri) => todo!(),
Exclusion::LiteralExclusion(LiteralExclusion::Literal(lit)) => {
todo!()
}
Exclusion::LiteralExclusion(LiteralExclusion::LiteralStem(stem)) => {
let mut map = serializer.serialize_map(Some(2))?;
map.serialize_entry("type", "LiteralStem")?;
map.serialize_entry("stem", stem)?;
map.end()
}
Exclusion::LanguageExclusion(_) => todo!(),
}
}
}

impl<'de> Deserialize<'de> for Exclusion {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
enum Field {
Type,
Stem,
}

impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
where
D: serde::Deserializer<'de>,
{
struct FieldVisitor;

impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("field of exclusion: `type` or `stem`")
}

fn visit_str<E>(self, value: &str) -> Result<Field, E>
where
E: de::Error,
{
match value {
"type" => Ok(Field::Type),
"stem" => Ok(Field::Stem),
_ => Err(de::Error::unknown_field(value, FIELDS)),
}
}
}

deserializer.deserialize_identifier(FieldVisitor)
}
}

struct ExclusionVisitor;

const FIELDS: &'static [&'static str] = &["type", "stem"];

impl<'de> Visitor<'de> for ExclusionVisitor {
type Value = Exclusion;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Exclusion value")
}

/*fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
FromStr::from_str(s)
.map_err(|e| de::Error::custom(format!("Error parsing string `{s}`: {e}")))
}*/

fn visit_map<V>(self, mut map: V) -> Result<Exclusion, V::Error>
where
V: MapAccess<'de>,
{
let mut type_: Option<ExclusionType> = None;
let mut stem: Option<String> = None;
while let Some(key) = map.next_key()? {
match key {
Field::Type => {
if type_.is_some() {
return Err(de::Error::duplicate_field("type"));
}
let value: String = map.next_value()?;

let parsed_type_ =
ExclusionType::parse(&value.as_str()).map_err(|e| {
de::Error::custom(format!(
"Error parsing Exclusion type, found: {value}. Error: {e:?}"
))
})?;
type_ = Some(parsed_type_);
}
Field::Stem => {
if stem.is_some() {
return Err(de::Error::duplicate_field("stem"));
}
stem = Some(map.next_value()?);
}
}
}
match type_ {
Some(ExclusionType::LiteralStem) => match stem {
Some(stem) => Ok(Exclusion::LiteralExclusion(
LiteralExclusion::LiteralStem(stem),
)),
None => Err(de::Error::missing_field("stem")),
},
Some(ExclusionType::LanguageStem) => match stem {
Some(stem) => Ok(Exclusion::LanguageExclusion(
LanguageExclusion::LanguageStem(stem),
)),
None => Err(de::Error::missing_field("stem")),
},
Some(ExclusionType::IriStem) => match stem {
Some(stem) => Ok(Exclusion::IriExclusion(IriExclusion::IriStem(stem))),
None => Err(de::Error::missing_field("stem")),
},
None => todo!(),
}
}
}

deserializer.deserialize_any(ExclusionVisitor)
}
}

#[derive(Debug, PartialEq)]
enum ExclusionType {
IriStem,
LiteralStem,
LanguageStem,
}

#[derive(Debug)]
struct ExclusionTypeError {
value: String,
}

impl ExclusionType {
fn parse(s: &str) -> Result<ExclusionType, ExclusionTypeError> {
match s {
"IriStem" => Ok(ExclusionType::IriStem),
"LanguageStem" => Ok(ExclusionType::LanguageStem),
"LiteralStem" => Ok(ExclusionType::LiteralStem),
_ => Err(ExclusionTypeError {
value: s.to_string(),
}),
}
}
}
36 changes: 20 additions & 16 deletions shex_ast/src/ast/iri_ref.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::{fmt::Display, str::FromStr};

use crate::{Deref, DerefError};
use iri_s::{IriS, IriSError};
use prefixmap::PrefixMap;
use serde_derive::{Deserialize, Serialize};
use void::Void;
use crate::{Deref, DerefError};

#[derive(Deserialize, Serialize, Debug, PartialEq, Hash, Eq, Clone)]
#[serde(try_from = "&str", into = "String")]
Expand Down Expand Up @@ -33,7 +32,6 @@ impl IriRef {
}
}
}

}

impl Deref for IriRef {
Expand All @@ -50,25 +48,32 @@ impl Deref for IriRef {
Ok(IriRef::Iri(iri))
}
},
IriRef::Prefixed { prefix, local } => {
match prefixmap {
None => Err(DerefError::NoPrefixMapPrefixedName {
prefix: prefix.clone(),
local: local.clone() }
),
Some(prefixmap) => {
let iri = prefixmap.resolve_prefix_local(prefix, local)?;
Ok(IriRef::Iri(iri))
}
IriRef::Prefixed { prefix, local } => match prefixmap {
None => Err(DerefError::NoPrefixMapPrefixedName {
prefix: prefix.clone(),
local: local.clone(),
}),
Some(prefixmap) => {
let iri = prefixmap.resolve_prefix_local(prefix, local)?;
Ok(IriRef::Iri(iri))
}
}
},
}
}
}

impl TryFrom<&str> for IriRef {
type Error = IriSError;
fn try_from(s: &str) -> Result<Self, Self::Error> {

fn try_from(value: &str) -> Result<Self, Self::Error> {
FromStr::from_str(value)
}
}

impl FromStr for IriRef {
type Err = IriSError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let iri_s = IriS::from_str(s)?;
Ok(IriRef::Iri(iri_s))
}
Expand Down Expand Up @@ -109,4 +114,3 @@ impl Display for IriRef {
Ok(())
}
}

2 changes: 2 additions & 0 deletions shex_ast/src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod annotation;
pub mod bnode;
pub mod deref;
pub mod exclusion;
pub mod iri;
pub mod iri_ref;
pub mod iri_ref_or_wildcard;
Expand Down Expand Up @@ -29,6 +30,7 @@ pub mod xs_facet;

use crate::ast::serde_string_or_struct::*;
pub use crate::deref::*;
pub use crate::exclusion::*;
pub use annotation::*;
pub use bnode::*;
pub use iri::*;
Expand Down
20 changes: 14 additions & 6 deletions shex_ast/src/ast/numeric_literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ use serde::{de::Visitor, Deserialize, Serialize, Serializer};
pub enum NumericLiteral {
Integer(isize),
Decimal(Decimal),
Double(Decimal),
Double(f64),
}

impl NumericLiteral {
/* pub fn double(d: f64) -> NumericLiteral {
NumericLiteral::Double(d)
}*/
pub fn decimal(d: Decimal) -> NumericLiteral {
NumericLiteral::Decimal(d)
}

pub fn decimal(whole: i64, fraction: u32) -> NumericLiteral {
pub fn decimal_from_parts(whole: i64, fraction: u32) -> NumericLiteral {
let s = format!("{whole}.{fraction}");
let d = Decimal::from_str_exact(s.as_str()).unwrap();
NumericLiteral::Decimal(d)
Expand All @@ -35,6 +35,10 @@ impl NumericLiteral {
pub fn integer(n: isize) -> NumericLiteral {
NumericLiteral::Integer(n)
}

pub fn double(d: f64) -> NumericLiteral {
NumericLiteral::Double(d)
}
}

impl Serialize for NumericLiteral {
Expand Down Expand Up @@ -134,7 +138,11 @@ impl<'de> Deserialize<'de> for NumericLiteral {

impl ToString for NumericLiteral {
fn to_string(&self) -> String {
todo!()
match self {
NumericLiteral::Double(d) => format!("{}", d),
NumericLiteral::Integer(n) => n.to_string(),
NumericLiteral::Decimal(d) => d.to_string(),
}
}
}

Expand Down
17 changes: 12 additions & 5 deletions shex_ast/src/ast/object_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ pub enum ObjectValue {
},
}

fn serialize_integer_literal<S>(v: &isize, serializer: S) -> result::Result<S::Ok, S::Error>
/*fn serialize_integer_literal<S>(v: &isize, serializer: S) -> result::Result<S::Ok, S::Error>
where
S: Serializer,
{
v.serialize(serializer)
}
}*/

impl ObjectValue {
pub fn integer(n: isize) -> ObjectValue {
Expand All @@ -49,9 +49,16 @@ impl ObjectValue {
}

pub fn bool(b: bool) -> ObjectValue {
let dt_boolean = IriRef::Iri(IriS::xsd_boolean());
ObjectValue::BooleanLiteral {
value: b
ObjectValue::BooleanLiteral { value: b }
}

pub fn lexical_form(&self) -> String {
match self {
ObjectValue::BooleanLiteral { value: true } => "true".to_string(),
ObjectValue::BooleanLiteral { value: false } => "false".to_string(),
ObjectValue::IriRef(iri) => iri.to_string(),
ObjectValue::NumericLiteral(n) => n.to_string(),
ObjectValue::ObjectLiteral { value, .. } => value.to_string(),
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions shex_ast/src/ast/schema_json_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,10 @@ fn cnv_value(v: &ast::ValueSetValue) -> CResult<ValueSetValue> {
ast::ValueSetValue::LiteralStemRange {
stem, exclusions, ..
} => {
let stem = cnv_string_or_wildcard(&stem)?;
todo!()
/*let stem = cnv_string_or_wildcard(&stem)?;
let exclusions = cnv_opt_vec(&exclusions, cnv_string_or_literalstem)?;
Ok(ValueSetValue::LiteralStemRange { stem, exclusions })
Ok(ValueSetValue::LiteralStemRange { stem, exclusions })*/
}
_ => todo!(),
}
Expand Down
Loading

0 comments on commit 6820deb

Please sign in to comment.