Skip to content

Commit

Permalink
Impl TryFromJsonSyntax for IdLayout.
Browse files Browse the repository at this point in the history
  • Loading branch information
timothee-haudebourg committed Mar 28, 2024
1 parent 9e426e4 commit 383646d
Show file tree
Hide file tree
Showing 19 changed files with 188 additions and 72 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ langtag = "0.4.0"
thiserror = "1.0.50"
serde = "1.0.192"
serde_json = { version = "1.0", features = ["arbitrary_precision"] }
# json-syntax = "0.12.2"
json-syntax = { path = "/home/timothee/Projets/utils/json/json-syntax" }

locspan = "0.8.2"
nquads-syntax = "0.19.0"
Expand Down
2 changes: 1 addition & 1 deletion generators/rust/treeldr-rs-macros/src/generate/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub enum Error {
Parse(#[from] crate::parse::Error),

#[error(transparent)]
Build(#[from] treeldr_layouts::abs::syntax::Error),
Build(#[from] treeldr_layouts::abs::syntax::BuildError),

#[error("invalid datatype `{0}`")]
InvalidDatatype(String),
Expand Down
2 changes: 1 addition & 1 deletion generators/rust/treeldr-rs-macros/src/generate/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub enum Error {
Parse(#[from] crate::parse::Error),

#[error(transparent)]
Build(#[from] treeldr_layouts::abs::syntax::Error),
Build(#[from] treeldr_layouts::abs::syntax::BuildError),

#[error("invalid datatype `{0}`")]
InvalidDatatype(String),
Expand Down
2 changes: 1 addition & 1 deletion generators/rust/treeldr-rs-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ enum Error {
Json(serde_json::Error),

#[error("build error: {0}")]
Layout(abs::syntax::Error),
Layout(abs::syntax::BuildError),
}

struct Attribute(syn::punctuated::Punctuated<syn::LitStr, syn::Token![,]>);
Expand Down
1 change: 1 addition & 0 deletions layouts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ serde = { workspace = true, features = ["derive"] }
thiserror.workspace = true
locspan.workspace = true
serde_json = "1.0"
json-syntax.workspace = true
lazy_static = "1.4.0"
static_assertions = "1.1.0"

Expand Down
14 changes: 7 additions & 7 deletions layouts/src/abs/syntax/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
use super::LayoutHeader;

#[derive(Debug, thiserror::Error)]
pub enum Error {
pub enum BuildError {
#[error("no base IRI to resolve `{0}`")]
NoBaseIri(IriRefBuf),

Expand Down Expand Up @@ -135,13 +135,13 @@ where
pub trait Build<C> {
type Target;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error>;
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError>;
}

impl<C, T: Build<C>> Build<C> for Box<T> {
type Target = T::Target;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
T::build(&**self, context, scope)
}
}
Expand All @@ -167,7 +167,7 @@ impl Scope {
/// Creates a new scope by combining this scope with the given layout
/// `header` which may define a new base IRI, new IRI prefixes and new
/// variables.
pub fn with_header(&self, header: &LayoutHeader) -> Result<Self, Error> {
pub fn with_header(&self, header: &LayoutHeader) -> Result<Self, BuildError> {
let mut result = self.clone();

if let Some(base_iri) = &header.base {
Expand Down Expand Up @@ -197,7 +197,7 @@ impl Scope {
pub fn with_intro<'s>(
&self,
intro: impl IntoIterator<Item = &'s String>,
) -> Result<Self, Error> {
) -> Result<Self, BuildError> {
let mut result = self.clone();

for name in intro {
Expand Down Expand Up @@ -240,10 +240,10 @@ impl Scope {
}

/// Returns the unique index of the given variable.
pub fn variable(&self, name: &str) -> Result<u32, Error> {
pub fn variable(&self, name: &str) -> Result<u32, BuildError> {
self.variables
.get(name)
.copied()
.ok_or_else(|| Error::UndeclaredVariable(name.to_owned()))
.ok_or_else(|| BuildError::UndeclaredVariable(name.to_owned()))
}
}
8 changes: 4 additions & 4 deletions layouts/src/abs/syntax/dataset.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};

use super::{Build, Context, Error, Pattern, Scope};
use super::{Build, Context, BuildError, Pattern, Scope};

#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(transparent)]
Expand All @@ -24,7 +24,7 @@ where
{
type Target = crate::Dataset<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let mut dataset = crate::Dataset::new();
for quad in &self.0 {
dataset.insert(quad.build(context, scope)?);
Expand All @@ -45,7 +45,7 @@ pub struct Quad(
impl<C: Context> Build<C> for Pattern {
type Target = crate::Pattern<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
match self {
Self::Var(name) => Ok(crate::Pattern::Var(scope.variable(name)?)),
Self::Iri(compact_iri) => {
Expand All @@ -67,7 +67,7 @@ impl<C: Context> Build<C> for Quad {
crate::Pattern<C::Resource>,
>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
Ok(rdf_types::Quad(
self.0.build(context, scope)?,
self.1.build(context, scope)?,
Expand Down
4 changes: 2 additions & 2 deletions layouts/src/abs/syntax/layout/intersection.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};

use crate::{
abs::syntax::{Build, Context, Error, Scope},
abs::syntax::{Build, Context, BuildError, Scope},
layout::LayoutType,
Ref,
};
Expand All @@ -21,7 +21,7 @@ pub struct IntersectionLayout {
impl<C: Context> Build<C> for IntersectionLayout {
type Target = Vec<Ref<LayoutType, C::Resource>>;

fn build(&self, _context: &mut C, _scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, _context: &mut C, _scope: &Scope) -> Result<Self::Target, BuildError> {
unimplemented!()
}
}
20 changes: 10 additions & 10 deletions layouts/src/abs/syntax/layout/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use crate::abs::{
self,
syntax::{
Build, CompactIri, Context, Dataset, Error, Pattern, Scope, ValueFormatOrLayout, ValueIntro,
Build, CompactIri, Context, Dataset, BuildError, Pattern, Scope, ValueFormatOrLayout, ValueIntro,
},
};

Expand Down Expand Up @@ -36,7 +36,7 @@ where
{
type Target = abs::layout::ListLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
match self {
Self::Ordered(l) => l
.build(context, scope)
Expand Down Expand Up @@ -114,7 +114,7 @@ where
{
type Target = abs::layout::list::ordered::NodeLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let head = scope.variable_count();
let rest = head + 1;
let first = rest + 1;
Expand Down Expand Up @@ -181,7 +181,7 @@ where
{
type Target = abs::layout::OrderedListLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let (header, scope) = self.header.build(context, scope)?;
Ok(abs::layout::OrderedListLayout {
input: header.input,
Expand All @@ -201,7 +201,7 @@ where
{
type Target = abs::layout::list::ordered::NodeLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let head = scope.variable_count();
let rest = head + 1;
let scope = scope.with_intro(
Expand Down Expand Up @@ -266,7 +266,7 @@ where
{
type Target = abs::layout::UnorderedListLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let subject = if self.header.input.is_empty() {
None
} else {
Expand All @@ -291,7 +291,7 @@ impl ListItem {
context: &mut C,
scope: &Scope,
subject: Option<u32>,
) -> Result<abs::layout::list::ItemLayout<C::Resource>, Error>
) -> Result<abs::layout::list::ItemLayout<C::Resource>, BuildError>
where
C::Resource: Clone,
{
Expand All @@ -316,9 +316,9 @@ impl ListItem {
None,
));
}
None => return Err(Error::NoPropertyObject),
None => return Err(BuildError::NoPropertyObject),
},
None => return Err(Error::NoPropertySubject),
None => return Err(BuildError::NoPropertySubject),
}
}

Expand Down Expand Up @@ -349,7 +349,7 @@ where
{
type Target = abs::layout::SizedListLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let subject = if self.header.input.is_empty() {
None
} else {
Expand Down
42 changes: 31 additions & 11 deletions layouts/src/abs/syntax/layout/literal.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use json_syntax::TryFromJsonSyntax;
use serde::{Deserialize, Serialize};

use crate::{
abs::{
self,
syntax::{Build, CompactIri, Context, Error, Pattern, Scope},
syntax::{check_type, expect_object, get_entry, Build, BuildError, CompactIri, Context, Error, Pattern, Scope},
RegExp,
},
Value,
Expand Down Expand Up @@ -36,7 +37,7 @@ where
{
type Target = abs::layout::LiteralLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
match self {
Self::Data(l) => Ok(abs::layout::LiteralLayout::Data(l.build(context, scope)?)),
Self::Id(l) => Ok(abs::layout::LiteralLayout::Id(l.build(context, scope)?)),
Expand Down Expand Up @@ -72,7 +73,7 @@ where
{
type Target = abs::layout::DataLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
match self {
Self::Unit(l) => l.build(context, scope).map(abs::layout::DataLayout::Unit),
Self::Boolean(l) => l
Expand Down Expand Up @@ -108,7 +109,7 @@ where
{
type Target = abs::layout::UnitLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let (header, _) = self.header.build(context, scope)?;
Ok(abs::layout::UnitLayout {
input: header.input,
Expand Down Expand Up @@ -140,12 +141,12 @@ fn literal_resource<C: Context>(
scope: &Scope,
input: &LayoutInput,
resource: Option<&Pattern>,
) -> Result<crate::Pattern<C::Resource>, Error> {
) -> Result<crate::Pattern<C::Resource>, BuildError> {
match resource {
Some(r) => r.build(context, scope),
None => {
if input.is_empty() {
Err(Error::MissingLiteralTargetResource)
Err(BuildError::MissingLiteralTargetResource)
} else {
Ok(crate::Pattern::Var(0))
}
Expand All @@ -159,7 +160,7 @@ where
{
type Target = abs::layout::BooleanLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let (header, scope) = self.header.build(context, scope)?;

Ok(abs::layout::BooleanLayout {
Expand Down Expand Up @@ -203,7 +204,7 @@ where
{
type Target = abs::layout::NumberLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let (header, scope) = self.header.build(context, scope)?;

Ok(abs::layout::NumberLayout {
Expand Down Expand Up @@ -242,7 +243,7 @@ where
{
type Target = abs::layout::ByteStringLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let (header, scope) = self.header.build(context, scope)?;

Ok(abs::layout::ByteStringLayout {
Expand Down Expand Up @@ -285,7 +286,7 @@ where
{
type Target = abs::layout::TextStringLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let (header, scope) = self.header.build(context, scope)?;

Ok(abs::layout::TextStringLayout {
Expand Down Expand Up @@ -325,13 +326,32 @@ pub struct IdLayout {
pub resource: Option<Pattern>,
}

impl TryFromJsonSyntax for IdLayout {
type Error = Error;

fn try_from_json_syntax_at(json: &json_syntax::Value, code_map: &json_syntax::CodeMap, offset: usize) -> Result<Self, Error> {
let object = expect_object(json, offset)?;
check_type(object, IdLayoutType::NAME, code_map, offset)?;
let header = LayoutHeader::try_from_json_syntax_at(object, code_map, offset)?;
let pattern = get_entry(object, "pattern", code_map, offset)?;
let resource = get_entry(object, "resource", code_map, offset)?;

Ok(Self {
type_: IdLayoutType,
header,
pattern,
resource
})
}
}

impl<C: Context> Build<C> for IdLayout
where
C::Resource: Clone,
{
type Target = abs::layout::IdLayout<C::Resource>;

fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, Error> {
fn build(&self, context: &mut C, scope: &Scope) -> Result<Self::Target, BuildError> {
let (header, scope) = self.header.build(context, scope)?;

Ok(abs::layout::IdLayout {
Expand Down
Loading

0 comments on commit 383646d

Please sign in to comment.