sdml_core/model/
values.rs

1/*!
2Provide the Rust types that implement *value*-related components of the SDML Grammar.
3*/
4use crate::model::{
5    members::{Ordering, Uniqueness},
6    IdentifierReference, Span,
7};
8use lazy_static::lazy_static;
9use ordered_float::OrderedFloat;
10use regex::Regex;
11use rust_decimal::Decimal;
12use sdml_errors::diagnostics::functions::invalid_language_tag;
13use std::{
14    fmt::{Debug, Display},
15    str::FromStr,
16};
17use url::Url;
18
19#[cfg(feature = "serde")]
20use serde::{Deserialize, Serialize};
21
22// ------------------------------------------------------------------------------------------------
23// Public Types ❱ Values
24// ------------------------------------------------------------------------------------------------
25
26/// Corresponds to the grammar rule `value`.
27#[derive(Clone, Debug)]
28#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
29pub enum Value {
30    Simple(SimpleValue),
31    ValueConstructor(ValueConstructor),
32    Mapping(MappingValue),
33    Reference(IdentifierReference),
34    List(SequenceOfValues),
35}
36
37/// Corresponds to the grammar rule `simple_value`.
38#[derive(Clone, Debug)]
39#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
40pub enum SimpleValue {
41    /// Corresponds to the grammar rule `boolean`.
42    Boolean(bool),
43    /// Corresponds to the grammar rule `double`.
44    Double(OrderedFloat<f64>),
45    /// Corresponds to the grammar rule `decimal`.
46    Decimal(Decimal),
47    /// Corresponds to the grammar rule `integer`.
48    Integer(i64),
49    /// Corresponds to the grammar rule `unsigned`.
50    Unsigned(u64),
51    /// Corresponds to the grammar rule `string`.
52    String(LanguageString),
53    /// Corresponds to the grammar rule `iri_reference`.
54    IriReference(Url),
55    /// Corresponds to the grammar rule `binary`.
56    Binary(Binary),
57}
58
59/// Corresponds to the grammar rule `binary`.
60#[derive(Clone, Debug)]
61#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
62pub struct Binary(Vec<u8>);
63
64/// Corresponds to the grammar rule `string`.
65#[derive(Clone, Debug)]
66#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
67pub struct LanguageString {
68    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
69    span: Option<Box<Span>>,
70    /// Corresponds to the grammar rule `quoted_string`.
71    value: String,
72    language: Option<LanguageTag>,
73}
74
75/// Corresponds to the grammar rule `language_tag`.
76#[derive(Clone, Debug)]
77#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
78pub struct LanguageTag {
79    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
80    span: Option<Box<Span>>,
81    value: language_tags::LanguageTag,
82}
83
84/// Corresponds to the grammar rule `mapping_value`.
85#[derive(Clone, Debug)]
86#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
87pub struct MappingValue {
88    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
89    span: Option<Box<Span>>,
90    domain: SimpleValue,
91    range: Box<Value>,
92}
93
94/// Corresponds to the grammar rule `list_of_values`.
95#[derive(Clone, Debug, Default)]
96#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
97pub struct SequenceOfValues {
98    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
99    span: Option<Box<Span>>,
100    ordering: Option<Ordering>,
101    uniqueness: Option<Uniqueness>,
102    values: Vec<SequenceMember>,
103}
104
105/// Corresponds to the grammar rule `name`.
106#[derive(Clone, Debug)]
107#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
108pub enum SequenceMember {
109    Simple(SimpleValue),
110    ValueConstructor(ValueConstructor),
111    Reference(IdentifierReference),
112    Mapping(MappingValue),
113}
114
115/// Corresponds to the grammar rule `value_constructor`.
116#[derive(Clone, Debug)]
117#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
118pub struct ValueConstructor {
119    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
120    span: Option<Box<Span>>,
121    type_name: IdentifierReference,
122    value: SimpleValue,
123}
124
125// ------------------------------------------------------------------------------------------------
126// Private Types
127// ------------------------------------------------------------------------------------------------
128
129lazy_static! {
130    static ref LANGUAGE_TAG: Regex =
131        Regex::new(r"^[a-z]{2,3}(-[A-Z]{3})?(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$").unwrap();
132}
133
134// ------------------------------------------------------------------------------------------------
135// Implementations ❱ Annotations ❱ Values
136// ------------------------------------------------------------------------------------------------
137
138impl From<SimpleValue> for Value {
139    fn from(v: SimpleValue) -> Self {
140        Self::Simple(v)
141    }
142}
143
144impl From<LanguageString> for Value {
145    fn from(v: LanguageString) -> Self {
146        Self::Simple(SimpleValue::String(v))
147    }
148}
149
150impl From<f64> for Value {
151    fn from(v: f64) -> Self {
152        Self::Simple(SimpleValue::Double(v.into()))
153    }
154}
155
156impl From<OrderedFloat<f64>> for Value {
157    fn from(v: OrderedFloat<f64>) -> Self {
158        Self::Simple(SimpleValue::Double(v))
159    }
160}
161
162impl From<Decimal> for Value {
163    fn from(v: Decimal) -> Self {
164        Self::Simple(SimpleValue::Decimal(v))
165    }
166}
167
168impl From<i64> for Value {
169    fn from(v: i64) -> Self {
170        Self::Simple(SimpleValue::Integer(v))
171    }
172}
173
174impl From<i32> for Value {
175    fn from(v: i32) -> Self {
176        Self::Simple(SimpleValue::Integer(v as i64))
177    }
178}
179
180impl From<u64> for Value {
181    fn from(v: u64) -> Self {
182        Self::Simple(SimpleValue::Unsigned(v))
183    }
184}
185
186impl From<u32> for Value {
187    fn from(v: u32) -> Self {
188        Self::Simple(SimpleValue::Unsigned(v as u64))
189    }
190}
191
192impl From<bool> for Value {
193    fn from(v: bool) -> Self {
194        Self::Simple(SimpleValue::Boolean(v))
195    }
196}
197
198impl From<Url> for Value {
199    fn from(v: Url) -> Self {
200        Self::Simple(SimpleValue::IriReference(v))
201    }
202}
203
204impl From<Binary> for Value {
205    fn from(v: Binary) -> Self {
206        Self::Simple(SimpleValue::Binary(v))
207    }
208}
209
210impl From<ValueConstructor> for Value {
211    fn from(v: ValueConstructor) -> Self {
212        Self::ValueConstructor(v)
213    }
214}
215
216impl From<IdentifierReference> for Value {
217    fn from(v: IdentifierReference) -> Self {
218        Self::Reference(v)
219    }
220}
221
222impl From<MappingValue> for Value {
223    fn from(v: MappingValue) -> Self {
224        Self::Mapping(v)
225    }
226}
227
228impl From<SequenceOfValues> for Value {
229    fn from(v: SequenceOfValues) -> Self {
230        Self::List(v)
231    }
232}
233
234enum_display_impl!(Value => Simple, ValueConstructor, Reference, Mapping, List);
235
236impl Value {
237    is_as_variant!(Simple (SimpleValue) => is_simple, as_simple);
238    is_as_variant!(ValueConstructor (ValueConstructor) => is_value_constructor, as_value_constructor);
239    is_as_variant!(Mapping (MappingValue) => is_mapping_value, as_mapping_value);
240    is_as_variant!(Reference (IdentifierReference) => is_reference, as_reference);
241    is_as_variant!(List (SequenceOfValues) => is_sequence, as_sequence);
242
243    pub const fn is_boolean(&self) -> bool {
244        matches!(self, Self::Simple(SimpleValue::Boolean(_)))
245    }
246
247    pub const fn as_boolean(&self) -> Option<bool> {
248        match self {
249            Self::Simple(SimpleValue::Boolean(v)) => Some(*v),
250            _ => None,
251        }
252    }
253
254    pub const fn is_double(&self) -> bool {
255        matches!(self, Self::Simple(SimpleValue::Double(_)))
256    }
257
258    pub const fn as_double(&self) -> Option<OrderedFloat<f64>> {
259        match self {
260            Self::Simple(SimpleValue::Double(v)) => Some(*v),
261            _ => None,
262        }
263    }
264
265    pub const fn is_decimal(&self) -> bool {
266        matches!(self, Self::Simple(SimpleValue::Decimal(_)))
267    }
268
269    pub const fn as_decimal(&self) -> Option<Decimal> {
270        match self {
271            Self::Simple(SimpleValue::Decimal(v)) => Some(*v),
272            _ => None,
273        }
274    }
275
276    pub const fn is_integer(&self) -> bool {
277        matches!(self, Self::Simple(SimpleValue::Integer(_)))
278    }
279
280    pub fn as_integer(&self) -> Option<i64> {
281        match self {
282            Self::Simple(SimpleValue::Integer(v)) => Some(*v),
283            _ => None,
284        }
285    }
286
287    pub const fn is_unsigned(&self) -> bool {
288        matches!(self, Self::Simple(SimpleValue::Unsigned(_)))
289    }
290
291    pub const fn as_unsigned(&self) -> Option<u64> {
292        match self {
293            Self::Simple(SimpleValue::Unsigned(v)) => Some(*v),
294            _ => None,
295        }
296    }
297
298    pub const fn is_string(&self) -> bool {
299        matches!(self, Self::Simple(SimpleValue::String(_)))
300    }
301
302    pub const fn as_string(&self) -> Option<&LanguageString> {
303        match self {
304            Self::Simple(SimpleValue::String(v)) => Some(v),
305            _ => None,
306        }
307    }
308
309    pub const fn is_iri(&self) -> bool {
310        matches!(self, Self::Simple(SimpleValue::IriReference(_)))
311    }
312
313    pub const fn as_iri(&self) -> Option<&Url> {
314        match self {
315            Self::Simple(SimpleValue::IriReference(v)) => Some(v),
316            _ => None,
317        }
318    }
319
320    pub const fn is_binary(&self) -> bool {
321        matches!(self, Self::Simple(SimpleValue::Binary(_)))
322    }
323
324    pub const fn as_binary(&self) -> Option<&Binary> {
325        match self {
326            Self::Simple(SimpleValue::Binary(v)) => Some(v),
327            _ => None,
328        }
329    }
330}
331
332// ------------------------------------------------------------------------------------------------
333
334impl_from_for_variant!(SimpleValue, Boolean, bool);
335
336impl_from_for_variant!(SimpleValue, Double, OrderedFloat<f64>);
337
338impl_from_for_variant!(SimpleValue, Decimal, Decimal);
339
340impl_from_for_variant!(SimpleValue, Integer, i64);
341
342impl_from_for_variant!(SimpleValue, Unsigned, u64);
343
344impl_from_for_variant!(SimpleValue, String, LanguageString);
345
346impl_from_for_variant!(SimpleValue, IriReference, Url);
347
348impl_from_for_variant!(SimpleValue, Binary, Binary);
349
350impl Display for SimpleValue {
351    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
352        write!(
353            f,
354            "{}",
355            match self {
356                Self::Double(v) => v.to_string(),
357                Self::Decimal(v) => v.to_string(),
358                Self::Integer(v) => v.to_string(),
359                Self::Unsigned(v) => v.to_string(),
360                Self::Boolean(v) => v.to_string(),
361                Self::IriReference(v) => format!("<{v}>"),
362                Self::String(v) => v.to_string(),
363                Self::Binary(v) => v.to_string(),
364            }
365        )
366    }
367}
368
369impl SimpleValue {
370    is_as_variant!(Boolean (bool) => is_boolean, as_boolean);
371    is_as_variant!(Double (OrderedFloat<f64>) => is_double, as_double);
372    is_as_variant!(Decimal (Decimal) => is_decimal, as_decimal);
373    is_as_variant!(Integer (i64) => is_integer, as_integer);
374    is_as_variant!(Unsigned (u64) => is_unsigned, as_unsigned);
375    is_as_variant!(String (LanguageString) => is_string, as_string);
376    is_as_variant!(IriReference (Url) => is_iri, as_iri);
377    is_as_variant!(Binary (Binary) => is_binary, as_binary);
378}
379
380// ------------------------------------------------------------------------------------------------
381
382impl Display for LanguageString {
383    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
384        write!(
385            f,
386            "{:?}{}",
387            self.value,
388            if let Some(language) = &self.language {
389                language.to_string()
390            } else {
391                String::new()
392            }
393        )
394    }
395}
396
397impl From<String> for LanguageString {
398    fn from(v: String) -> Self {
399        Self::new(&v, None)
400    }
401}
402
403impl From<&str> for LanguageString {
404    fn from(v: &str) -> Self {
405        Self::new(v, None)
406    }
407}
408
409impl PartialEq for LanguageString {
410    fn eq(&self, other: &Self) -> bool {
411        self.value == other.value && self.language == other.language
412    }
413}
414
415impl Eq for LanguageString {}
416
417impl_has_source_span_for!(LanguageString);
418
419impl LanguageString {
420    // --------------------------------------------------------------------------------------------
421    // LanguageString :: Constructors
422    // --------------------------------------------------------------------------------------------
423
424    pub fn new(value: &str, language: Option<LanguageTag>) -> Self {
425        Self {
426            span: None,
427            value: value.to_string(),
428            language,
429        }
430    }
431
432    // --------------------------------------------------------------------------------------------
433    // LanguageString :: Fields
434    // --------------------------------------------------------------------------------------------
435
436    get_and_set!(pub value, set_value => String);
437
438    get_and_set!(pub language, set_language, unset_language => optional has_language, LanguageTag);
439
440    // --------------------------------------------------------------------------------------------
441    // LanguageString :: Helpers
442    // --------------------------------------------------------------------------------------------
443
444    pub fn eq_with_span(&self, other: &Self) -> bool {
445        self.span == other.span && self.value == other.value && self.language == other.language
446    }
447}
448
449// ------------------------------------------------------------------------------------------------
450
451impl Display for LanguageTag {
452    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
453        write!(f, "@{}", self.value)
454    }
455}
456
457impl FromStr for LanguageTag {
458    type Err = crate::error::Error;
459
460    fn from_str(s: &str) -> Result<Self, Self::Err> {
461        if Self::is_valid_str(s) {
462            Ok(Self {
463                span: None,
464                value: language_tags::LanguageTag::parse(s)?,
465            })
466        } else {
467            Err(invalid_language_tag(0, None, s).into())
468        }
469    }
470}
471
472impl From<LanguageTag> for language_tags::LanguageTag {
473    fn from(value: LanguageTag) -> Self {
474        value.value
475    }
476}
477
478impl From<LanguageTag> for String {
479    fn from(value: LanguageTag) -> Self {
480        value.value.to_string()
481    }
482}
483
484impl AsRef<language_tags::LanguageTag> for LanguageTag {
485    fn as_ref(&self) -> &language_tags::LanguageTag {
486        &self.value
487    }
488}
489
490impl AsRef<str> for LanguageTag {
491    fn as_ref(&self) -> &str {
492        self.value.as_str()
493    }
494}
495
496impl PartialEq for LanguageTag {
497    fn eq(&self, other: &Self) -> bool {
498        self.value == other.value
499    }
500}
501
502impl PartialEq<language_tags::LanguageTag> for LanguageTag {
503    fn eq(&self, other: &language_tags::LanguageTag) -> bool {
504        self.value == *other
505    }
506}
507
508impl PartialEq<str> for LanguageTag {
509    fn eq(&self, other: &str) -> bool {
510        self.value.as_str() == other
511    }
512}
513
514impl Eq for LanguageTag {}
515
516impl_has_source_span_for!(LanguageTag);
517
518impl LanguageTag {
519    // --------------------------------------------------------------------------------------------
520    // LanguageTag :: Constructors
521    // --------------------------------------------------------------------------------------------
522
523    pub fn new_unchecked(s: &str) -> Self {
524        Self {
525            span: None,
526            value: language_tags::LanguageTag::parse(s).unwrap(),
527        }
528    }
529
530    // --------------------------------------------------------------------------------------------
531    // LanguageTag :: Helpers
532    // --------------------------------------------------------------------------------------------
533
534    pub fn is_valid_str(s: &str) -> bool {
535        language_tags::LanguageTag::parse(s).is_ok()
536    }
537
538    pub fn eq_with_span(&self, other: &Self) -> bool {
539        self.span == other.span && self.value == other.value
540    }
541
542    pub fn inner(&self) -> &language_tags::LanguageTag {
543        &self.value
544    }
545
546    pub fn into_inner(self) -> language_tags::LanguageTag {
547        self.value
548    }
549}
550
551// ------------------------------------------------------------------------------------------------
552
553impl Display for Binary {
554    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
555        write!(f, "[")?;
556        for byte in self.as_bytes() {
557            write!(f, "{:02X}", byte)?;
558        }
559        write!(f, "[")
560    }
561}
562
563impl From<Vec<u8>> for Binary {
564    fn from(v: Vec<u8>) -> Self {
565        Self(v)
566    }
567}
568
569impl FromIterator<u8> for Binary {
570    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
571        Self(Vec::from_iter(iter))
572    }
573}
574
575impl AsRef<Vec<u8>> for Binary {
576    fn as_ref(&self) -> &Vec<u8> {
577        &self.0
578    }
579}
580
581impl Binary {
582    pub fn as_bytes(&self) -> &[u8] {
583        self.0.as_slice()
584    }
585
586    pub fn default_format(&self) -> String {
587        self.format(1, 2)
588    }
589
590    pub fn format(&self, indent_level: u8, indent_spaces: u8) -> String {
591        let mut buffer = String::new();
592        let n = (indent_level * indent_spaces) as usize;
593        let indent_outer = format!("{:n$}", "");
594        let n = ((indent_level + 1) * indent_spaces) as usize;
595        let indent_inner = format!("{:n$}", "");
596        if self.0.len() <= 16 {
597            buffer.push_str("#[");
598            buffer.push_str(&format_byte_block(self.0.as_slice(), &indent_inner));
599            buffer.push(']');
600        } else {
601            buffer.push_str(&format!("#[\n{indent_outer}"));
602            buffer.push_str(&format_byte_block(self.0.as_slice(), &indent_inner));
603            buffer.push_str(&format!("\n{indent_outer}]"));
604        }
605        buffer
606    }
607}
608
609fn format_byte_block(bytes: &[u8], indent: &str) -> String {
610    if bytes.len() <= 8 {
611        bytes
612            .iter()
613            .map(|b| format!("{:02X}", b))
614            .collect::<Vec<String>>()
615            .join(" ")
616    } else if bytes.len() <= 16 {
617        format!(
618            "{}   {}",
619            format_byte_block(&bytes[0..8], indent),
620            format_byte_block(&bytes[9..], indent),
621        )
622    } else {
623        format!(
624            "{indent}{}\n{}",
625            format_byte_block(&bytes[0..16], indent),
626            format_byte_block(&bytes[17..], indent),
627        )
628    }
629}
630
631// ------------------------------------------------------------------------------------------------
632
633impl Display for MappingValue {
634    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
635        write!(f, "{} -> {}", self.domain, self.range)
636    }
637}
638
639impl_has_source_span_for!(MappingValue);
640
641impl MappingValue {
642    // --------------------------------------------------------------------------------------------
643    // MappingValue :: Constructors
644    // --------------------------------------------------------------------------------------------
645
646    pub fn new(domain: SimpleValue, range: Value) -> Self {
647        Self {
648            span: None,
649            domain,
650            range: Box::new(range),
651        }
652    }
653
654    // --------------------------------------------------------------------------------------------
655    // MappingValue :: Fields
656    // --------------------------------------------------------------------------------------------
657
658    get_and_set!(pub domain, set_domain => into SimpleValue);
659
660    get_and_set!(pub range, set_range => boxed into Value);
661}
662
663// ------------------------------------------------------------------------------------------------
664
665impl Display for SequenceOfValues {
666    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
667        write!(
668            f,
669            "[{}]",
670            self.values
671                .iter()
672                .map(|v| v.to_string())
673                .collect::<Vec<String>>()
674                .join(" ")
675        )
676    }
677}
678
679impl From<Vec<SequenceMember>> for SequenceOfValues {
680    fn from(values: Vec<SequenceMember>) -> Self {
681        Self {
682            span: None,
683            ordering: None,
684            uniqueness: None,
685            values,
686        }
687    }
688}
689
690impl FromIterator<SequenceMember> for SequenceOfValues {
691    fn from_iter<T: IntoIterator<Item = SequenceMember>>(iter: T) -> Self {
692        Self::from(Vec::from_iter(iter))
693    }
694}
695
696impl_has_source_span_for!(SequenceOfValues);
697
698impl_as_sequence!(pub SequenceOfValues => SequenceMember);
699
700impl SequenceOfValues {
701    // --------------------------------------------------------------------------------------------
702    // SequenceOfValues :: Fields
703    // --------------------------------------------------------------------------------------------
704
705    pub fn with_ordering(self, ordering: Ordering) -> Self {
706        Self {
707            ordering: Some(ordering),
708            ..self
709        }
710    }
711
712    get_and_set!(pub ordering, set_ordering, unset_ordering => optional has_ordering, Ordering);
713
714    pub fn with_uniqueness(self, uniqueness: Uniqueness) -> Self {
715        Self {
716            uniqueness: Some(uniqueness),
717            ..self
718        }
719    }
720
721    get_and_set!(pub uniqueness, set_uniqueness, unset_uniqueness => optional has_uniqueness, Uniqueness);
722}
723
724// ------------------------------------------------------------------------------------------------
725
726impl_from_for_variant!(SequenceMember, Simple, SimpleValue);
727
728impl_from_for_variant!(SequenceMember, ValueConstructor, ValueConstructor);
729
730impl_from_for_variant!(SequenceMember, Reference, IdentifierReference);
731
732enum_display_impl!(SequenceMember => Simple, ValueConstructor, Reference, Mapping);
733
734// ------------------------------------------------------------------------------------------------
735
736impl Display for ValueConstructor {
737    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
738        write!(f, "{}({})", self.type_name, self.value)
739    }
740}
741
742impl_has_source_span_for!(ValueConstructor);
743
744impl ValueConstructor {
745    // --------------------------------------------------------------------------------------------
746    // ValueConstructor :: Constructors
747    // --------------------------------------------------------------------------------------------
748
749    pub const fn new(type_name: IdentifierReference, value: SimpleValue) -> Self {
750        Self {
751            span: None,
752            type_name,
753            value,
754        }
755    }
756
757    // --------------------------------------------------------------------------------------------
758    // ValueConstructor :: Fields
759    // --------------------------------------------------------------------------------------------
760
761    get_and_set!(pub type_name, set_type_name => IdentifierReference);
762
763    get_and_set!(pub value, set_value => SimpleValue);
764}