use std::fmt;
use langtag::{LangTag, LangTagBuf};
use rdf_types::{
BTreeDataset, BTreeGraph, IndexedBTreeDataset, IndexedBTreeGraph,
diff::{ColoredRdfDiff, RdfDiff},
};
pub trait RdfDisplay {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
#[inline(always)]
fn rdf_display(&self) -> RdfDisplayed<&Self> {
RdfDisplayed(self)
}
}
impl RdfDisplay for str {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use fmt::Display;
write!(f, "\"")?;
for c in self.chars() {
match c {
'"' => write!(f, "\\\""),
'\\' => write!(f, "\\\\"),
'\n' => write!(f, "\\n"),
'\r' => write!(f, "\\r"),
c => c.fmt(f),
}?
}
write!(f, "\"")
}
}
impl RdfDisplay for String {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_str().rdf_fmt(f)
}
}
impl RdfDisplay for iref::IriRef {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<")?;
for c in self.as_str().chars() {
match c {
'\x00'..='\x20' | '<' | '>' | '"' | '{' | '}' | '|' | '^' | '`' | '\\' => {
let bytes: u32 = c.into();
write!(f, "\\u{bytes:#04x}")
}
_ => fmt::Display::fmt(&c, f),
}?;
}
write!(f, ">")
}
}
impl RdfDisplay for iref::Iri {
#[inline(always)]
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_iri_ref().rdf_fmt(f)
}
}
impl RdfDisplay for iref::IriBuf {
#[inline(always)]
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_iri_ref().rdf_fmt(f)
}
}
impl RdfDisplay for iref::IriRefBuf {
#[inline(always)]
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_iri_ref().rdf_fmt(f)
}
}
impl RdfDisplay for LangTag {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use fmt::Display;
self.as_str().fmt(f)
}
}
impl RdfDisplay for LangTagBuf {
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use fmt::Display;
self.as_str().fmt(f)
}
}
impl<T: RdfDisplay + ?Sized> RdfDisplay for &T {
#[inline(always)]
fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
T::rdf_fmt(*self, f)
}
}
pub struct RdfDisplayed<T>(T);
impl<T: RdfDisplay> fmt::Display for RdfDisplayed<T> {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.rdf_fmt(f)
}
}
impl<R: RdfDisplay> RdfDisplay for BTreeGraph<R> {
fn rdf_fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for t in self {
writeln!(f, "{} .", t.rdf_display())?;
}
Ok(())
}
}
impl<R: RdfDisplay> RdfDisplay for IndexedBTreeGraph<R> {
fn rdf_fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for t in self {
writeln!(f, "{} .", t.rdf_display())?;
}
Ok(())
}
}
impl<R: RdfDisplay> RdfDisplay for BTreeDataset<R> {
fn rdf_fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for t in self {
writeln!(f, "{} .", t.rdf_display())?;
}
Ok(())
}
}
impl<R: RdfDisplay> RdfDisplay for IndexedBTreeDataset<R> {
fn rdf_fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for t in self {
writeln!(f, "{} .", t.rdf_display())?;
}
Ok(())
}
}
impl<R: RdfDisplay> RdfDisplay for RdfDiff<R> {
fn rdf_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for quad in &self.added {
writeln!(f, "+ {} .", quad.rdf_display())?;
}
for quad in &self.removed {
writeln!(f, "- {} .", quad.rdf_display())?;
}
Ok(())
}
}
impl<'a, R: RdfDisplay> RdfDisplay for ColoredRdfDiff<'a, R> {
fn rdf_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for quad in &self.0.added {
writeln!(f, "\x1b[32m+ {} .\x1b[0m", quad.rdf_display())?;
}
for quad in &self.0.removed {
writeln!(f, "\x1b[31m- {} .\x1b[0m", quad.rdf_display())?;
}
Ok(())
}
}