shex_ast/ast/
shape_expr_label.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use std::{fmt::Display, str::FromStr};

use iri_s::{IriS, IriSError};
use regex::Regex;
use serde_derive::{Deserialize, Serialize};

use prefixmap::{Deref, DerefError, IriRef};
use thiserror::Error;

use super::bnode::BNode;

#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Hash, Clone)]
#[serde(try_from = "&str", into = "String")]
pub enum ShapeExprLabel {
    IriRef { value: IriRef },
    BNode { value: BNode },
    Start,
}

impl ShapeExprLabel {
    pub fn iri_unchecked(s: &str) -> Self {
        ShapeExprLabel::IriRef {
            value: IriS::new_unchecked(s).into(),
        }
    }

    pub fn iri_ref(i: IriRef) -> Self {
        ShapeExprLabel::IriRef { value: i }
    }

    pub fn iri(iri: IriS) -> Self {
        ShapeExprLabel::IriRef {
            value: IriRef::iri(iri),
        }
    }

    pub fn bnode(bn: BNode) -> Self {
        ShapeExprLabel::BNode { value: bn }
    }

    pub fn prefixed(alias: &str, local: &str) -> Self {
        ShapeExprLabel::IriRef {
            value: IriRef::prefixed(alias, local),
        }
    }

    pub fn start() -> Self {
        ShapeExprLabel::Start
    }
}

impl Deref for ShapeExprLabel {
    fn deref(
        &self,
        base: &Option<iri_s::IriS>,
        prefixmap: &Option<prefixmap::PrefixMap>,
    ) -> Result<Self, DerefError>
    where
        Self: Sized,
    {
        match self {
            ShapeExprLabel::IriRef { value } => {
                let new_value = value.deref(base, prefixmap)?;
                Ok(ShapeExprLabel::IriRef { value: new_value })
            }
            ShapeExprLabel::BNode { value } => Ok(ShapeExprLabel::BNode {
                value: value.clone(),
            }),
            ShapeExprLabel::Start => Ok(ShapeExprLabel::Start),
        }
    }
}

impl TryFrom<&str> for ShapeExprLabel {
    type Error = RefError;

    fn try_from(s: &str) -> Result<Self, Self::Error> {
        let re_iri = Regex::new(r"<(.*)>").unwrap();
        if let Some(iri_str) = re_iri.captures(s) {
            let iri_s = IriS::from_str(&iri_str[1])?;
            Ok(ShapeExprLabel::IriRef {
                value: IriRef::iri(iri_s),
            })
        } else {
            let re_bnode = Regex::new(r"_:(.*)").unwrap();
            if let Some(bnode_s) = re_bnode.captures(s) {
                Ok(ShapeExprLabel::BNode {
                    value: BNode::new(&bnode_s[1]),
                })
            } else {
                let iri_s = IriS::from_str(s)?;
                Ok(ShapeExprLabel::IriRef {
                    value: IriRef::iri(iri_s),
                })
            }
        }
    }
}

impl Display for ShapeExprLabel {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let str = match self {
            ShapeExprLabel::IriRef { value } => value.to_string(),
            ShapeExprLabel::BNode { value } => value.to_string(),
            ShapeExprLabel::Start => "START".to_string(),
        };
        write!(f, "{}", str)
    }
}

impl From<ShapeExprLabel> for String {
    fn from(val: ShapeExprLabel) -> Self {
        val.to_string()
    }
}

impl From<&ShapeExprLabel> for String {
    fn from(val: &ShapeExprLabel) -> Self {
        val.to_string()
    }
}

impl FromStr for ShapeExprLabel {
    type Err = RefError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        TryFrom::try_from(s)
    }
}

#[derive(Error, Debug)]
pub enum RefError {
    #[error("Cannot parse as IriS")]
    IriSError(#[from] IriSError),

    #[error("Cannot parse as Iri or BNode: {str}")]
    BadRef { str: String },
}