shex_ast/ir/
shape_label.rs

1use iri_s::{IriS, IriSError};
2use serde::Serialize;
3use std::{fmt::Display, str::FromStr};
4use thiserror::Error;
5
6use crate::BNode;
7
8#[derive(PartialEq, Eq, Hash, Debug, Clone)]
9pub enum ShapeLabel {
10    Iri(IriS),
11    BNode(BNode),
12    Start,
13}
14
15impl ShapeLabel {
16    pub fn iri(i: IriS) -> ShapeLabel {
17        ShapeLabel::Iri(i)
18    }
19    pub fn from_bnode(bn: BNode) -> ShapeLabel {
20        ShapeLabel::BNode(bn)
21    }
22
23    pub fn from_iri_str(s: &str) -> Result<ShapeLabel, IriSError> {
24        let iri = IriS::from_str(s)?;
25        Ok(ShapeLabel::Iri(iri))
26    }
27}
28
29impl Display for ShapeLabel {
30    fn fmt(&self, dest: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
31        match self {
32            ShapeLabel::Iri(iri) => write!(dest, "{iri}"),
33            ShapeLabel::BNode(bnode) => write!(dest, "{bnode}"),
34            ShapeLabel::Start => write!(dest, "Start"),
35        }
36    }
37}
38
39impl TryFrom<&str> for ShapeLabel {
40    type Error = ShapeLabelError;
41
42    #[allow(irrefutable_let_patterns)]
43    fn try_from(s: &str) -> Result<Self, Self::Error> {
44        if s == "Start" {
45            Ok(ShapeLabel::Start)
46        } else if let Ok(iri) = IriS::from_str(s) {
47            Ok(ShapeLabel::Iri(iri))
48        } else if let Ok(bnode) = BNode::try_from(s) {
49            Ok(ShapeLabel::BNode(bnode))
50        } else {
51            Err(ShapeLabelError::InvalidStr(s.to_string()))
52        }
53    }
54}
55
56#[derive(Error, Debug, Clone)]
57
58pub enum ShapeLabelError {
59    #[error("Invalid ShapeLabel string: {0}")]
60    InvalidStr(String),
61}
62
63impl Serialize for ShapeLabel {
64    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
65    where
66        S: serde::Serializer,
67    {
68        match self {
69            ShapeLabel::Iri(iri) => serializer.serialize_str(&iri.to_string()),
70            ShapeLabel::BNode(bnode) => serializer.serialize_str(&bnode.to_string()),
71            ShapeLabel::Start => serializer.serialize_str("Start"),
72        }
73    }
74}