linked_data_core/attributes/
variant.rs1use iref::IriBuf;
2use snafu::ResultExt;
3use syn::spanned::Spanned;
4
5use crate::attributes::ast::VariantAttribute;
6use crate::attributes::parse_ld_attributes;
7use crate::prefix_mappings::PrefixMappings;
8use crate::{Error, InvalidMappingSnafu};
9
10pub struct RdfVariantAttributes {
11 pub predicate_path: PredicatePath,
12}
13
14pub enum PredicatePath {
15 ChainedPath {
19 to_blank: IriBuf,
20 from_blank: IriBuf,
21 },
22
23 Predicate(IriBuf),
26}
27
28impl RdfVariantAttributes {
29 pub fn try_from_attrs(
30 variant: &syn::Variant,
31 inner_attrs: Vec<syn::Attribute>,
32 outer_attrs: Vec<syn::Attribute>,
33 prefix_mappings: &PrefixMappings,
34 ) -> Result<Self, Error> {
35 let inner_attrs: Vec<VariantAttribute> = parse_ld_attributes(&inner_attrs)?;
36 let outer_attrs: Vec<VariantAttribute> = parse_ld_attributes(&outer_attrs)?;
37
38 let unpack_variant_attrs = |attrs: &[VariantAttribute]| -> Result<Option<IriBuf>, Error> {
39 if let Some(VariantAttribute::Iri(iri)) = attrs.get(1) {
40 Err(Error::MultipleIris { span: iri.span() })
41 } else {
42 attrs
43 .first()
44 .map(|variant_attr| match variant_attr {
45 VariantAttribute::Iri(lit_str) => lit_str,
46 })
47 .map(|lit_str| {
48 prefix_mappings
49 .expand(lit_str.value())
50 .context(InvalidMappingSnafu {
51 span: lit_str.span(),
52 })
53 })
54 .transpose()
55 }
56 };
57
58 let inner_attr = unpack_variant_attrs(&inner_attrs)?;
59 let outer_attr = unpack_variant_attrs(&outer_attrs)?;
60
61 match (inner_attr, outer_attr) {
62 (None, None) => Err(Error::MissingIriAttribute {
63 span: variant.span(),
64 }),
65 (None, Some(outer_iri)) => Ok(RdfVariantAttributes {
66 predicate_path: PredicatePath::Predicate(outer_iri),
67 }),
68 (Some(inner_iri), None) => Ok(RdfVariantAttributes {
69 predicate_path: PredicatePath::Predicate(inner_iri),
70 }),
71 (Some(to_blank), Some(from_blank)) => Ok(RdfVariantAttributes {
72 predicate_path: PredicatePath::ChainedPath {
73 to_blank,
74 from_blank,
75 },
76 }),
77 }
78 }
79}