use core::fmt;
use std::borrow::Cow;
use std::cmp::Ordering;
use into_owned_trait::IntoOwned;
use langtag::LangTag;
use crate::RdfDisplay;
use super::{CowLiteralType, Literal, LiteralRef};
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct CowLiteral<'a> {
pub value: Cow<'a, str>,
pub r#type: CowLiteralType<'a>,
}
impl<'a> CowLiteral<'a> {
pub fn new(value: impl Into<Cow<'a, str>>, type_: impl Into<CowLiteralType<'a>>) -> Self {
Self {
value: value.into(),
r#type: type_.into(),
}
}
pub fn as_str(&self) -> &str {
&self.value
}
pub fn as_bytes(&self) -> &[u8] {
self.value.as_bytes()
}
pub fn is_lang_string(&self) -> bool {
self.r#type.is_lang_string()
}
pub fn lang_tag(&self) -> Option<&LangTag> {
self.r#type.lang_tag()
}
pub fn as_ref(&self) -> LiteralRef<'_> {
LiteralRef::new(&self.value, self.r#type.as_ref())
}
pub fn into_owned(self) -> Literal {
Literal::new(self.value, self.r#type)
}
}
impl IntoOwned for CowLiteral<'_> {
type Owned = Literal;
fn into_owned(self) -> Literal {
Literal::new(self.value, self.r#type)
}
}
impl<'a> From<&'a Literal> for CowLiteral<'a> {
fn from(value: &'a Literal) -> Self {
Self::new(&value.value, value.r#type.as_ref())
}
}
impl<'a> From<LiteralRef<'a>> for CowLiteral<'a> {
fn from(value: LiteralRef<'a>) -> Self {
Self::new(value.value, value.r#type)
}
}
impl From<Literal> for CowLiteral<'_> {
fn from(value: Literal) -> Self {
value.into_cow()
}
}
impl From<CowLiteral<'_>> for Literal {
fn from(value: CowLiteral<'_>) -> Self {
value.into_owned()
}
}
impl PartialEq<Literal> for CowLiteral<'_> {
fn eq(&self, other: &Literal) -> bool {
self.as_ref() == *other
}
}
impl PartialEq<CowLiteral<'_>> for Literal {
fn eq(&self, other: &CowLiteral<'_>) -> bool {
*self == other.as_ref()
}
}
impl<'a> PartialEq<LiteralRef<'a>> for CowLiteral<'_> {
fn eq(&self, other: &LiteralRef<'a>) -> bool {
self.as_ref() == *other
}
}
impl PartialEq<CowLiteral<'_>> for LiteralRef<'_> {
fn eq(&self, other: &CowLiteral<'_>) -> bool {
*self == other.as_ref()
}
}
impl PartialOrd<Literal> for CowLiteral<'_> {
fn partial_cmp(&self, other: &Literal) -> Option<Ordering> {
self.as_ref().partial_cmp(other)
}
}
impl PartialOrd<CowLiteral<'_>> for Literal {
fn partial_cmp(&self, other: &CowLiteral<'_>) -> Option<Ordering> {
self.partial_cmp(&other.as_ref())
}
}
impl<'a> PartialOrd<LiteralRef<'a>> for CowLiteral<'_> {
fn partial_cmp(&self, other: &LiteralRef<'a>) -> Option<Ordering> {
self.as_ref().partial_cmp(other)
}
}
impl PartialOrd<CowLiteral<'_>> for LiteralRef<'_> {
fn partial_cmp(&self, other: &CowLiteral<'_>) -> Option<Ordering> {
self.partial_cmp(&other.as_ref())
}
}
impl equivalent::Equivalent<Literal> for CowLiteral<'_> {
fn equivalent(&self, key: &Literal) -> bool {
self == key
}
}
impl equivalent::Comparable<Literal> for CowLiteral<'_> {
fn compare(&self, key: &Literal) -> std::cmp::Ordering {
self.partial_cmp(key).unwrap()
}
}
impl AsRef<str> for CowLiteral<'_> {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl AsRef<[u8]> for CowLiteral<'_> {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
impl fmt::Display for CowLiteral<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.rdf_fmt(f)?;
if self.r#type.is_xsd_string() {
Ok(())
} else {
self.r#type.rdf_fmt(f)
}
}
}
impl RdfDisplay for CowLiteral<'_> {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.rdf_fmt(f)?;
if self.r#type.is_xsd_string() {
Ok(())
} else {
self.r#type.rdf_fmt(f)
}
}
}