rdfx 0.23.1

RDF 1.2 data-structures, traits and utilities: terms (incl. triple terms), triples, quads, interpretations, graphs, datasets, unstar/restar reification helpers.
Documentation
use core::fmt;
use std::{borrow::Borrow, cmp::Ordering};

use educe::Educe;
use langtag::LangTag;

use crate::RdfDisplay;

use super::{CowLiteral, Literal, LiteralTypeRef};

/// RDF Literal reference.
#[derive(Educe, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
#[educe(Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct LiteralRef<'a> {
    /// Literal value.
    pub value: &'a str,

    /// Literal type.
    pub type_: LiteralTypeRef<'a>,
}

impl<'a> LiteralRef<'a> {
    pub const fn new(value: &'a str, type_: LiteralTypeRef<'a>) -> Self {
        Self { value, type_ }
    }

    pub const fn as_type(&self) -> LiteralTypeRef<'a> {
        self.type_
    }

    pub const fn as_type_mut(&mut self) -> &mut LiteralTypeRef<'a> {
        &mut self.type_
    }

    pub const fn into_type(self) -> LiteralTypeRef<'a> {
        self.type_
    }

    pub const fn as_value(&self) -> &'a str {
        self.value
    }

    pub const fn into_value(self) -> &'a str {
        self.value
    }

    pub const fn into_parts(self) -> (&'a str, LiteralTypeRef<'a>) {
        (self.value, self.type_)
    }

    pub const fn as_str(&self) -> &'a str {
        self.value
    }

    pub fn as_bytes(&self) -> &'a [u8] {
        self.value.as_ref()
    }

    pub const fn is_lang_string(&self) -> bool {
        self.type_.is_lang_string()
    }

    pub const fn is_undirected_lang_string(&self) -> bool {
        self.type_.is_undirected_lang_string()
    }

    pub const fn is_dir_lang_string(&self) -> bool {
        self.type_.is_dir_lang_string()
    }

    pub const fn lang_tag(&self) -> Option<&'a LangTag> {
        self.type_.lang_tag()
    }

    pub const fn direction(&self) -> Option<crate::Direction> {
        self.type_.direction()
    }

    pub fn into_cow(self) -> CowLiteral<'a> {
        CowLiteral::new(self.value, self.type_)
    }
}

impl LiteralRef<'_> {
    pub fn to_owned(self) -> Literal {
        Literal::new(self.value.to_owned(), self.type_.into_owned())
    }

    pub fn cloned(self) -> Literal {
        self.to_owned()
    }
}

impl<'a> PartialEq<LiteralRef<'a>> for Literal {
    fn eq(&self, other: &LiteralRef<'a>) -> bool {
        self.type_ == other.type_ && self.value == other.value
    }
}

impl PartialEq<Literal> for LiteralRef<'_> {
    fn eq(&self, other: &Literal) -> bool {
        self.type_ == other.type_ && self.value == other.value
    }
}

impl equivalent::Equivalent<Literal> for LiteralRef<'_> {
    fn equivalent(&self, key: &Literal) -> bool {
        self == key
    }
}

impl<'a> PartialOrd<LiteralRef<'a>> for Literal {
    fn partial_cmp(&self, other: &LiteralRef<'a>) -> Option<Ordering> {
        Some(self.value.as_str().partial_cmp(other.value)?.then(self.type_.partial_cmp(&other.type_)?))
    }
}

impl PartialOrd<Literal> for LiteralRef<'_> {
    fn partial_cmp(&self, other: &Literal) -> Option<Ordering> {
        Some(self.value.partial_cmp(other.value.as_str())?.then(self.type_.partial_cmp(&other.type_)?))
    }
}

impl Borrow<str> for LiteralRef<'_> {
    fn borrow(&self) -> &str {
        self.as_str()
    }
}

impl AsRef<str> for LiteralRef<'_> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl fmt::Display for LiteralRef<'_> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.value.rdf_fmt(f)?;
        if self.type_.is_xsd_string() { Ok(()) } else { self.type_.rdf_fmt(f) }
    }
}

impl RdfDisplay for LiteralRef<'_> {
    fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.value.rdf_fmt(f)?;
        if self.type_.is_xsd_string() { Ok(()) } else { self.type_.rdf_fmt(f) }
    }
}