Skip to content

Commit

Permalink
make bool implement Term and FromTerm
Browse files Browse the repository at this point in the history
fix #159

also improve recognized datatypes for i32, isize and usize
  • Loading branch information
pchampin committed Mar 21, 2024
1 parent 86ca1b8 commit 642e02f
Showing 1 changed file with 70 additions and 1 deletion.
71 changes: 70 additions & 1 deletion api/src/term/_native_literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ lazy_static::lazy_static! {
static ref XSD_DOUBLE: Box<str> = xsd::double.iri().unwrap().unwrap().into();
static ref XSD_INTEGER: Box<str> = xsd::integer.iri().unwrap().unwrap().into();
static ref XSD_STRING: Box<str> = xsd::string.iri().unwrap().unwrap().into();
static ref XSD_BOOLEAN: Box<str> = xsd::boolean.iri().unwrap().unwrap().into();
}

/// [`f64`] implements [`Term`]
Expand Down Expand Up @@ -189,6 +190,42 @@ impl Term for str {
}
}

/// [`bool`] implements [`Term`]
/// so that Rust literals can be used as RDF literals in code.
///
/// E.g.:
/// ```
/// # use sophia_api::graph::{MutableGraph, Graph};
/// # use sophia_api::term::SimpleTerm;
/// # use sophia_api::ns::{rdf, rdfs};
/// # use sophia_iri::IriRef;
/// # fn test<T: MutableGraph>(graph: &mut T) -> Result<(), Box<dyn std::error::Error>> {
/// # let subject: IriRef<&'static str> = IriRef::new("")?;
/// #
/// graph.insert(&subject, &rdf::value, true)?;
/// #
/// # Ok(()) }
/// ```
impl Term for bool {
type BorrowTerm<'x> = Self;

fn kind(&self) -> TermKind {
TermKind::Literal
}
fn lexical_form(&self) -> Option<MownStr> {
Some(MownStr::from(if *self { "true" } else { "false" }))
}
fn datatype(&self) -> Option<IriRef<MownStr>> {
Some(IriRef::new_unchecked(MownStr::from_str(&XSD_BOOLEAN)))
}
fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
None
}
fn borrow_term(&self) -> Self::BorrowTerm<'_> {
*self
}
}

/// [`f64`] implements [`TryFromTerm`]
/// so that compatible datatypes can easily be converted to native Rust values.
impl TryFromTerm for f64 {
Expand Down Expand Up @@ -226,6 +263,8 @@ impl TryFromTerm for i32 {
|| Term::eq(&term.datatype().unwrap(), xsd::unsignedByte)
|| Term::eq(&term.datatype().unwrap(), xsd::nonNegativeInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::nonPositiveInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::negativeInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::positiveInteger)
{
lex.parse()
} else {
Expand Down Expand Up @@ -254,6 +293,8 @@ impl TryFromTerm for isize {
|| Term::eq(&term.datatype().unwrap(), xsd::unsignedByte)
|| Term::eq(&term.datatype().unwrap(), xsd::nonNegativeInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::nonPositiveInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::negativeInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::positiveInteger)
{
lex.parse()
} else {
Expand Down Expand Up @@ -281,7 +322,7 @@ impl TryFromTerm for usize {
|| Term::eq(&term.datatype().unwrap(), xsd::unsignedShort)
|| Term::eq(&term.datatype().unwrap(), xsd::unsignedByte)
|| Term::eq(&term.datatype().unwrap(), xsd::nonNegativeInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::nonPositiveInteger)
|| Term::eq(&term.datatype().unwrap(), xsd::positiveInteger)
{
lex.parse()
} else {
Expand All @@ -293,6 +334,24 @@ impl TryFromTerm for usize {
}
}

/// [`bool`] implements [`TryFromTerm`]
/// so that compatible datatypes can easily be converted to native Rust values.
impl TryFromTerm for bool {
type Error = std::str::ParseBoolError;

fn try_from_term<T: Term>(term: T) -> Result<Self, Self::Error> {
if let Some(lex) = term.lexical_form() {
if Term::eq(&term.datatype().unwrap(), xsd::boolean) {
lex.parse()
} else {
"wrong datatype".parse()
}
} else {
"not a literal".parse()
}
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down Expand Up @@ -348,6 +407,16 @@ mod test {
assert_eq!(lit.borrow_term(), lit);
}

#[test]
fn bool_as_literal() {
let lit = false;
assert_consistent_term_impl::<bool>(&lit);
assert_eq!(lit.kind(), TermKind::Literal);
assert_eq!(lit.lexical_form().unwrap(), "false");
assert_eq!(lit.datatype(), xsd::boolean.iri());
assert_eq!(lit.borrow_term(), lit);
}

#[test]
fn iri_to_native() {
assert!(f64::try_from_term(xsd::ID).is_err());
Expand Down

0 comments on commit 642e02f

Please sign in to comment.