linked-data-core 0.2.3

Core library for Linked Data crates
Documentation
use proc_macro2::{Span, TokenStream};
use quote::ToTokens;
use snafu::Snafu;

mod attributes;
mod prefix_mappings;
mod rdf_metadata;

pub use crate::attributes::variant::PredicatePath;
pub use crate::rdf_metadata::{RdfEnum, RdfField, RdfStruct, RdfType, RdfVariant};

pub trait TokenGenerator: Sized {
  fn generate_type_tokens(linked_data_type: &RdfType<Self>, tokens: &mut TokenStream);

  fn generate_struct_tokens(r#struct: &RdfStruct<Self>, tokens: &mut TokenStream);

  fn generate_enum_tokens(r#enum: &RdfEnum<Self>, tokens: &mut TokenStream);

  fn generate_variant_tokens(variant: &RdfVariant<Self>, tokens: &mut TokenStream);

  fn generate_field_tokens(field: &RdfField<Self>, tokens: &mut TokenStream);
}

impl<G: TokenGenerator> ToTokens for RdfType<G> {
  fn to_tokens(&self, tokens: &mut TokenStream) {
    G::generate_type_tokens(self, tokens)
  }
}

impl<F: TokenGenerator> ToTokens for RdfEnum<F> {
  fn to_tokens(&self, tokens: &mut TokenStream) {
    F::generate_enum_tokens(self, tokens)
  }
}

impl<F: TokenGenerator> ToTokens for RdfStruct<F> {
  fn to_tokens(&self, tokens: &mut TokenStream) {
    F::generate_struct_tokens(self, tokens)
  }
}

impl<F: TokenGenerator> ToTokens for RdfVariant<F> {
  fn to_tokens(&self, tokens: &mut TokenStream) {
    F::generate_variant_tokens(self, tokens)
  }
}

impl<F: TokenGenerator> ToTokens for RdfField<F> {
  fn to_tokens(&self, tokens: &mut TokenStream) {
    F::generate_field_tokens(self, tokens)
  }
}

#[derive(Debug, Snafu)]
pub enum Error {
  #[snafu(display("union types are not supported"))]
  UnionType { span: Span },

  #[snafu(display("struct variants are not supported"))]
  StructVariant { span: Span },

  #[snafu(display(
    "an enum must either have only unit variants (a closed list of RDF resources) or only \
    single-field variants (a tagged union); mixing both is not supported"
  ))]
  MixedVariantKinds { span: Span },

  #[snafu(transparent)]
  MalformedAttribute { source: syn::Error },

  #[snafu(display("type attribute is only allowed once"))]
  MultipleTypes { span: Span },

  #[snafu(display("multiple path IRIs defined"))]
  MultipleIris { span: Span },

  #[snafu(display("missing IRI path"))]
  MissingIriAttribute { span: Span },

  #[snafu(display("{source}"))]
  InvalidIri {
    source: oxiri::IriParseError,
    span: Span,
  },

  #[snafu(display("{source}"))]
  InvalidMapping {
    source: prefix_mappings::Error,
    span: Span,
  },
}

impl Error {
  fn span(&self) -> Span {
    match self {
      Error::UnionType { span } => *span,
      Error::StructVariant { span } => *span,
      Error::MixedVariantKinds { span } => *span,
      Error::MalformedAttribute { source } => source.span(),
      Error::InvalidIri { span, .. } => *span,
      Error::InvalidMapping { span, .. } => *span,
      Error::MultipleTypes { span } => *span,
      Error::MultipleIris { span } => *span,
      Error::MissingIriAttribute { span } => *span,
    }
  }
}