feat: improve erroring

pull/795/head
Jesse Wright 1 year ago
parent c6ceb38473
commit c9a3820244
  1. 21
      lib/oxrdf/src/blank_node.rs
  2. 45
      lib/oxrdf/src/cast_error.rs
  3. 2
      lib/oxrdf/src/lib.rs
  4. 27
      lib/oxrdf/src/literal.rs
  5. 27
      lib/oxrdf/src/named_node.rs
  6. 97
      lib/oxrdf/src/triple.rs

@ -1,4 +1,4 @@
use crate::{Term, TermCastError, TermCastErrorKind}; use crate::{Term, TryFromTermError};
use rand::random; use rand::random;
use std::io::Write; use std::io::Write;
use std::{fmt, str}; use std::{fmt, str};
@ -234,17 +234,14 @@ impl<'a> From<BlankNodeRef<'a>> for BlankNode {
} }
impl TryFrom<Term> for BlankNode { impl TryFrom<Term> for BlankNode {
type Error = TermCastError; type Error = TryFromTermError;
#[inline] #[inline]
fn try_from(term: Term) -> Result<Self, Self::Error> { fn try_from(term: Term) -> Result<Self, Self::Error> {
if let Term::BlankNode(node) = term { if let Term::BlankNode(node) = term {
Ok(node) Ok(node)
} else { } else {
Err( Err(TryFromTermError { term, target: "BlankNode" })
TermCastErrorKind::Msg(format!("Cannot convert term to a blank node: {}", term))
.into(),
)
} }
} }
} }
@ -381,17 +378,23 @@ mod tests {
#[test] #[test]
fn casting() { fn casting() {
let bnode: Result<BlankNode, TermCastError> = let bnode: Result<BlankNode, TryFromTermError> =
Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into(); Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into();
assert_eq!(bnode.unwrap(), BlankNode::new_from_unique_id(0x42)); assert_eq!(bnode.unwrap(), BlankNode::new_from_unique_id(0x42));
let literal: Result<BlankNode, TermCastError> = let literal: Result<BlankNode, TryFromTermError> =
Term::Literal(Literal::new_simple_literal("Hello World!")).try_into(); Term::Literal(Literal::new_simple_literal("Hello World!")).try_into();
assert_eq!(literal.is_err(), true); assert_eq!(literal.is_err(), true);
let err = literal.unwrap_err();
assert_eq!(err.to_string(), "\"Hello World!\" can not be converted to a BlankNode");
assert_eq!(Term::from(err), Term::Literal(Literal::new_simple_literal("Hello World!")));
let named_node: Result<BlankNode, TermCastError> = let named_node: Result<BlankNode, TryFromTermError> =
Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into(); Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into();
assert_eq!(named_node.is_err(), true); assert_eq!(named_node.is_err(), true);
let named_node_error = named_node.unwrap_err();
assert_eq!(named_node_error.to_string(), "<http://example.org/test> can not be converted to a BlankNode");
assert_eq!(Term::from(named_node_error), Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()));
} }
#[test] #[test]

@ -1,15 +1,38 @@
use std::error::Error; use std::{fmt, str};
/// An error return if trying to cast a term as something it cannot be converted to.
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct TermCastError(#[from] pub TermCastErrorKind);
/// An error return if trying to cast a term as something it cannot be converted to. use crate::{NamedNode, Subject, Term};
// An error return if trying to cast a term as something it cannot be converted to.
#[derive(Debug, Clone, thiserror::Error)]
#[error("{term} can not be converted to a {target}")]
pub struct TryFromTermError {
pub(crate) term: Term,
pub(crate) target: &'static str
}
impl From<TryFromTermError> for Term {
#[inline]
fn from(error: TryFromTermError) -> Self {
error.term
}
}
// An error return if trying to construct an invalid triple.
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum TermCastErrorKind { pub struct TripleConstructionError {
#[error("{0}")] pub(crate) subject: Result<Subject, TryFromTermError>,
Msg(String), pub(crate) predicate: Result<NamedNode, TryFromTermError>,
#[error("{0}")] pub(crate) object: Term,
Other(#[source] Box<dyn Error + Send + Sync + 'static>), }
impl fmt::Display for TripleConstructionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match (self.subject.clone().err(), self.predicate.clone().err()) {
(Some(e), Some(e2)) => write!(f, "subject: [{}], predicate: [{}]", e, e2),
(Some(e), _) => write!(f, "subject: [{}]", e),
(_, Some(e)) => write!(f, "predicate: [{}]", e),
_ => write!(f, "object: {}", self.object)
}
}
} }

@ -17,7 +17,7 @@ mod variable;
pub mod vocab; pub mod vocab;
pub use crate::blank_node::{BlankNode, BlankNodeIdParseError, BlankNodeRef}; pub use crate::blank_node::{BlankNode, BlankNodeIdParseError, BlankNodeRef};
pub use crate::cast_error::{TermCastError, TermCastErrorKind}; pub use crate::cast_error::TryFromTermError;
pub use crate::dataset::Dataset; pub use crate::dataset::Dataset;
pub use crate::graph::Graph; pub use crate::graph::Graph;
pub use crate::literal::{Literal, LiteralRef}; pub use crate::literal::{Literal, LiteralRef};

@ -1,6 +1,6 @@
use crate::named_node::NamedNode; use crate::named_node::NamedNode;
use crate::vocab::{rdf, xsd}; use crate::vocab::{rdf, xsd};
use crate::{NamedNodeRef, Term, TermCastError, TermCastErrorKind}; use crate::{NamedNodeRef, Term, TryFromTermError};
use oxilangtag::{LanguageTag, LanguageTagParseError}; use oxilangtag::{LanguageTag, LanguageTagParseError};
#[cfg(feature = "oxsdatatypes")] #[cfg(feature = "oxsdatatypes")]
use oxsdatatypes::*; use oxsdatatypes::*;
@ -423,17 +423,14 @@ impl From<DayTimeDuration> for Literal {
} }
impl TryFrom<Term> for Literal { impl TryFrom<Term> for Literal {
type Error = TermCastError; type Error = TryFromTermError;
#[inline] #[inline]
fn try_from(term: Term) -> Result<Self, Self::Error> { fn try_from(term: Term) -> Result<Self, Self::Error> {
if let Term::Literal(node) = term { if let Term::Literal(node) = term {
Ok(node) Ok(node)
} else { } else {
Err( Err(TryFromTermError { term, target: "Literal" })
TermCastErrorKind::Msg(format!("Cannot convert term to a literal: {}", term))
.into(),
)
} }
} }
} }
@ -678,20 +675,28 @@ mod tests {
#[test] #[test]
fn casting() { fn casting() {
let literal: Result<Literal, TermCastError> = let literal: Result<Literal, TryFromTermError> =
Term::Literal(Literal::new_simple_literal("Hello World!")).try_into(); Term::Literal(Literal::new_simple_literal("Hello World!")).try_into();
assert_eq!( assert_eq!(
literal.unwrap(), literal.unwrap(),
Literal::new_simple_literal("Hello World!") Literal::new_simple_literal("Hello World!")
); );
let bnode: Result<Literal, TermCastError> = let bnode: Result<Literal, TryFromTermError> =
Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into(); Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into();
assert_eq!(bnode.is_err(), true); let bnode_err = bnode.unwrap_err();
assert_eq!(bnode_err.term, Term::BlankNode(BlankNode::new_from_unique_id(0x42)));
assert_eq!(bnode_err.target, "Literal");
assert_eq!(bnode_err.to_string(), "_:42 can not be converted to a Literal");
assert_eq!(Term::from(bnode_err), Term::BlankNode(BlankNode::new_from_unique_id(0x42)));
let named_node: Result<Literal, TermCastError> = let named_node: Result<Literal, TryFromTermError> =
Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into(); Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into();
assert_eq!(named_node.is_err(), true); let named_node_err = named_node.unwrap_err();
assert_eq!(named_node_err.term, Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()));
assert_eq!(named_node_err.target, "Literal");
assert_eq!(named_node_err.to_string(), "<http://example.org/test> can not be converted to a Literal");
assert_eq!(Term::from(named_node_err), Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()));
} }
#[test] #[test]

@ -1,4 +1,4 @@
use crate::{Term, TermCastError, TermCastErrorKind}; use crate::{Term, TryFromTermError};
use oxiri::{Iri, IriParseError}; use oxiri::{Iri, IriParseError};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt; use std::fmt;
@ -237,17 +237,14 @@ impl<'a> From<Iri<&'a str>> for NamedNodeRef<'a> {
} }
impl TryFrom<Term> for NamedNode { impl TryFrom<Term> for NamedNode {
type Error = TermCastError; type Error = TryFromTermError;
#[inline] #[inline]
fn try_from(term: Term) -> Result<Self, Self::Error> { fn try_from(term: Term) -> Result<Self, Self::Error> {
if let Term::NamedNode(node) = term { if let Term::NamedNode(node) = term {
Ok(node) Ok(node)
} else { } else {
Err( Err(TryFromTermError { term, target: "NamedNode" })
TermCastErrorKind::Msg(format!("Cannot convert term to a named node: {}", term))
.into(),
)
} }
} }
} }
@ -262,19 +259,27 @@ mod tests {
#[test] #[test]
fn casting() { fn casting() {
let named_node: Result<NamedNode, TermCastError> = let named_node: Result<NamedNode, TryFromTermError> =
Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into(); Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into();
assert_eq!( assert_eq!(
named_node.unwrap(), named_node.unwrap(),
NamedNode::new("http://example.org/test").unwrap() NamedNode::new("http://example.org/test").unwrap()
); );
let literal: Result<NamedNode, TermCastError> = let literal: Result<NamedNode, TryFromTermError> =
Term::Literal(Literal::new_simple_literal("Hello World!")).try_into(); Term::Literal(Literal::new_simple_literal("Hello World!")).try_into();
assert_eq!(literal.is_err(), true); let literal_err = literal.unwrap_err();
assert_eq!(literal_err.term, Term::Literal(Literal::new_simple_literal("Hello World!")));
assert_eq!(literal_err.target, "NamedNode");
assert_eq!(literal_err.to_string(), "\"Hello World!\" can not be converted to a NamedNode");
assert_eq!(Term::from(literal_err), Term::Literal(Literal::new_simple_literal("Hello World!")));
let bnode: Result<NamedNode, TermCastError> = let bnode: Result<NamedNode, TryFromTermError> =
Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into(); Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into();
assert_eq!(bnode.is_err(), true); let bnode_err = bnode.unwrap_err();
assert_eq!(bnode_err.term, Term::BlankNode(BlankNode::new_from_unique_id(0x42)));
assert_eq!(bnode_err.target, "NamedNode");
assert_eq!(bnode_err.to_string(), "_:42 can not be converted to a NamedNode");
assert_eq!(Term::from(bnode_err), Term::BlankNode(BlankNode::new_from_unique_id(0x42)));
} }
} }

@ -1,8 +1,8 @@
use crate::blank_node::BlankNode; use crate::blank_node::BlankNode;
use crate::cast_error::TermCastErrorKind; use crate::cast_error::TripleConstructionError;
use crate::literal::Literal; use crate::literal::Literal;
use crate::named_node::NamedNode; use crate::named_node::NamedNode;
use crate::{BlankNodeRef, LiteralRef, NamedNodeRef, TermCastError}; use crate::{BlankNodeRef, LiteralRef, NamedNodeRef, TryFromTermError};
use std::fmt; use std::fmt;
/// The owned union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node). /// The owned union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
@ -225,7 +225,7 @@ impl From<BlankNodeRef<'_>> for Subject {
} }
impl TryFrom<Term> for Subject { impl TryFrom<Term> for Subject {
type Error = TermCastError; type Error = TryFromTermError;
#[inline] #[inline]
fn try_from(term: Term) -> Result<Self, Self::Error> { fn try_from(term: Term) -> Result<Self, Self::Error> {
@ -234,11 +234,7 @@ impl TryFrom<Term> for Subject {
Term::BlankNode(node) => Ok(Subject::BlankNode(node)), Term::BlankNode(node) => Ok(Subject::BlankNode(node)),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
Term::Triple(triple) => Ok(Subject::Triple(triple)), Term::Triple(triple) => Ok(Subject::Triple(triple)),
Term::Literal(literal) => Err(TermCastErrorKind::Msg(format!( Term::Literal(_) => Err(TryFromTermError { term, target: "Subject" }),
"Cannot convert a literal to a subject: {}",
literal
))
.into()),
} }
} }
} }
@ -764,12 +760,14 @@ impl Triple {
subject: impl Into<Term>, subject: impl Into<Term>,
predicate: impl Into<Term>, predicate: impl Into<Term>,
object: impl Into<Term>, object: impl Into<Term>,
) -> Result<Self, TermCastError> { ) -> Result<Self, TripleConstructionError> {
Ok(Self { let subject: Result<Subject, TryFromTermError> = TryInto::<Subject>::try_into(subject.into());
subject: TryInto::<Subject>::try_into(subject.into())?, let predicate: Result<NamedNode, TryFromTermError> = TryInto::<NamedNode>::try_into(predicate.into());
predicate: TryInto::<NamedNode>::try_into(predicate.into())?, if let (Ok (subject), Ok (predicate)) = (subject.clone(), predicate.clone()) {
object: object.into(), Ok(Self { subject, predicate, object: object.into() })
}) } else {
Err(TripleConstructionError { subject, predicate, object: object.into() })
}
} }
/// Encodes that this triple is in an [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset). /// Encodes that this triple is in an [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
@ -802,14 +800,14 @@ impl fmt::Display for Triple {
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
impl TryFrom<Term> for Box<Triple> { impl TryFrom<Term> for Box<Triple> {
type Error = TermCastError; type Error = TryFromTermError;
#[inline] #[inline]
fn try_from(term: Term) -> Result<Self, Self::Error> { fn try_from(term: Term) -> Result<Self, Self::Error> {
if let Term::Triple(node) = term { if let Term::Triple(node) = term {
Ok(node) Ok(node)
} else { } else {
Err(TermCastErrorKind::Msg(format!("Cannot convert term to a triple: {}", term)).into()) Err(TryFromTermError { term, target: "Box<Triple>" })
} }
} }
} }
@ -1289,20 +1287,32 @@ mod tests {
}; };
let triple_box = Box::new(triple); let triple_box = Box::new(triple);
let t: Result<Box<Triple>, TermCastError> = Term::Triple(triple_box.clone()).try_into(); let t: Result<Box<Triple>, TryFromTermError> = Term::Triple(triple_box.clone()).try_into();
assert_eq!(t.unwrap(), triple_box.clone()); assert_eq!(t.unwrap(), triple_box.clone());
let literal: Result<Box<Triple>, TermCastError> = let literal: Result<Box<Triple>, TryFromTermError> =
Term::Literal(Literal::new_simple_literal("Hello World!")).try_into(); Term::Literal(Literal::new_simple_literal("Hello World!")).try_into();
assert_eq!(literal.is_err(), true); let literal_err = literal.unwrap_err();
assert_eq!(literal_err.term, Term::Literal(Literal::new_simple_literal("Hello World!")));
assert_eq!(literal_err.target, "Box<Triple>");
assert_eq!(literal_err.to_string(), "\"Hello World!\" can not be converted to a Box<Triple>");
assert_eq!(Term::from(literal_err), Term::Literal(Literal::new_simple_literal("Hello World!")));
let bnode: Result<Box<Triple>, TermCastError> = let bnode: Result<Box<Triple>, TryFromTermError> =
Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into(); Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into();
assert_eq!(bnode.is_err(), true); let bnode_err = bnode.unwrap_err();
assert_eq!(bnode_err.term, Term::BlankNode(BlankNode::new_from_unique_id(0x42)));
assert_eq!(bnode_err.target, "Box<Triple>");
assert_eq!(bnode_err.to_string(), "_:42 can not be converted to a Box<Triple>");
assert_eq!(Term::from(bnode_err), Term::BlankNode(BlankNode::new_from_unique_id(0x42)));
let named_node: Result<Box<Triple>, TermCastError> = let named_node: Result<Box<Triple>, TryFromTermError> =
Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into(); Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into();
assert_eq!(named_node.is_err(), true); let named_node_err = named_node.unwrap_err();
assert_eq!(named_node_err.term, Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()));
assert_eq!(named_node_err.target, "Box<Triple>");
assert_eq!(named_node_err.to_string(), "<http://example.org/test> can not be converted to a Box<Triple>");
assert_eq!(Term::from(named_node_err), Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()));
} }
#[test] #[test]
@ -1321,7 +1331,7 @@ mod tests {
NamedNode::new("http://example.org/test").unwrap(), NamedNode::new("http://example.org/test").unwrap(),
); );
let bad_triple: Result<Triple, TermCastError> = Triple::new_from_terms( let bad_triple: Result<Triple, TripleConstructionError> = Triple::new_from_terms(
Term::Literal(Literal::new_simple_literal("abc123")), Term::Literal(Literal::new_simple_literal("abc123")),
Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()), Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()),
Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()), Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()),
@ -1333,6 +1343,12 @@ mod tests {
NamedNode::new("http://example.org/test").unwrap(), NamedNode::new("http://example.org/test").unwrap(),
); );
let bad_triple_3 = Triple::new_from_terms(
Term::Literal(Literal::new_simple_literal("abc123")),
BlankNode::new_from_unique_id(0x42),
NamedNode::new("http://example.org/test").unwrap(),
);
let triple: Triple = Triple::new( let triple: Triple = Triple::new(
Subject::NamedNode(NamedNode::new("http://example.org/test").unwrap()), Subject::NamedNode(NamedNode::new("http://example.org/test").unwrap()),
NamedNode::new("http://example.org/test").unwrap(), NamedNode::new("http://example.org/test").unwrap(),
@ -1350,8 +1366,30 @@ mod tests {
assert_eq!(unwrapped, triple); assert_eq!(unwrapped, triple);
assert_eq!(unwrapped, triple_2.clone()); assert_eq!(unwrapped, triple_2.clone());
assert_eq!(optional_triple_2.unwrap(), triple_2); assert_eq!(optional_triple_2.unwrap(), triple_2);
assert_eq!(bad_triple.is_err(), true); let bad_triple_err = bad_triple.unwrap_err();
assert_eq!(bad_triple_err.to_string(), "subject: [\"abc123\" can not be converted to a Subject]");
assert_eq!(bad_triple_err.subject.clone().unwrap_err().clone().term, Term::Literal(Literal::new_simple_literal("abc123")));
assert_eq!(bad_triple_err.subject.clone().unwrap_err().clone().target, "Subject");
assert_eq!(bad_triple_err.subject.unwrap_err().clone().to_string(), "\"abc123\" can not be converted to a Subject");
assert_eq!(bad_triple_2.is_err(), true); assert_eq!(bad_triple_2.is_err(), true);
let bad_triple_2_err = bad_triple_2.unwrap_err();
assert_eq!(bad_triple_2_err.to_string(), "subject: [\"abc123\" can not be converted to a Subject]");
assert_eq!(bad_triple_2_err.subject.clone().unwrap_err().clone().term, Term::Literal(Literal::new_simple_literal("abc123")));
assert_eq!(bad_triple_2_err.subject.clone().unwrap_err().clone().target, "Subject");
assert_eq!(bad_triple_2_err.subject.unwrap_err().clone().to_string(), "\"abc123\" can not be converted to a Subject");
assert_eq!(bad_triple_2_err.predicate.unwrap(), NamedNode::new("http://example.org/test").unwrap());
assert_eq!(bad_triple_2_err.object, Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()));
assert_eq!(bad_triple_3.is_err(), true);
let bad_triple_3_err = bad_triple_3.unwrap_err();
assert_eq!(bad_triple_3_err.to_string(), "subject: [\"abc123\" can not be converted to a Subject], predicate: [_:42 can not be converted to a NamedNode]");
assert_eq!(bad_triple_3_err.subject.clone().unwrap_err().clone().term, Term::Literal(Literal::new_simple_literal("abc123")));
assert_eq!(bad_triple_3_err.subject.clone().unwrap_err().clone().target, "Subject");
assert_eq!(bad_triple_3_err.subject.unwrap_err().clone().to_string(), "\"abc123\" can not be converted to a Subject");
assert_eq!(bad_triple_3_err.predicate.clone().unwrap_err().clone().term, Term::BlankNode(BlankNode::new_from_unique_id(0x42)));
assert_eq!(bad_triple_3_err.predicate.clone().unwrap_err().clone().target, "NamedNode");
assert_eq!(bad_triple_3_err.predicate.unwrap_err().clone().to_string(), "_:42 can not be converted to a NamedNode");
} }
#[test] #[test]
@ -1363,21 +1401,22 @@ mod tests {
}; };
let triple_box = Box::new(triple); let triple_box = Box::new(triple);
let t: Result<Subject, TermCastError> = Term::Triple(triple_box.clone()).try_into(); let t: Result<Subject, TryFromTermError> = Term::Triple(triple_box.clone()).try_into();
assert_eq!(t.unwrap(), Subject::Triple(triple_box.clone())); assert_eq!(t.unwrap(), Subject::Triple(triple_box.clone()));
let literal: Result<Subject, TermCastError> = let literal: Result<Subject, TryFromTermError> =
Term::Literal(Literal::new_simple_literal("Hello World!")).try_into(); Term::Literal(Literal::new_simple_literal("Hello World!")).try_into();
assert_eq!(literal.is_err(), true); assert_eq!(literal.is_err(), true);
assert_eq!(literal.is_err(), true);
let bnode: Result<Subject, TermCastError> = let bnode: Result<Subject, TryFromTermError> =
Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into(); Term::BlankNode(BlankNode::new_from_unique_id(0x42)).try_into();
assert_eq!( assert_eq!(
bnode.unwrap(), bnode.unwrap(),
Subject::BlankNode(BlankNode::new_from_unique_id(0x42)) Subject::BlankNode(BlankNode::new_from_unique_id(0x42))
); );
let named_node: Result<Subject, TermCastError> = let named_node: Result<Subject, TryFromTermError> =
Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into(); Term::NamedNode(NamedNode::new("http://example.org/test").unwrap()).try_into();
assert_eq!( assert_eq!(
named_node.unwrap(), named_node.unwrap(),

Loading…
Cancel
Save