use std::io::{BufReader, BufWriter, stdin, stdout};
use sophia::api::prelude::*;
use sophia::api::source::StreamError::{SinkError, SourceError};
#[cfg(feature = "jsonld")]
use sophia::jsonld::{JsonLdOptions, serializer::JsonLdSerializer};
use sophia::turtle::parser::gnq;
use sophia::turtle::serializer::{
nq::NQuadsSerializer,
nt::NTriplesSerializer,
trig::{TriGConfig, TriGSerializer},
turtle::{TurtleConfig, TurtleSerializer},
};
#[cfg(feature = "xml")]
use sophia::xml::serializer::{RdfXmlConfig, RdfXmlSerializer};
fn main() {
let input = BufReader::new(stdin());
let quad_source = gnq::parse_bufread(input);
let out = BufWriter::new(stdout());
let pretty: bool = std::env::var("SOPHIA_PRETTY")
.unwrap_or_else(|_| "false".into())
.parse()
.unwrap();
let format = std::env::args()
.nth(1)
.unwrap_or_else(|| "trig".to_string());
let res = match &format[..] {
"ntriples" | "nt" => serialize_triples(quad_source, NTriplesSerializer::new(out)),
"turtle" | "ttl" => {
let config = TurtleConfig::new().with_pretty(pretty);
let ser = TurtleSerializer::new_with_config(out, config);
serialize_triples(quad_source, ser)
}
"nquads" | "nq" => serialize_quads(quad_source, NQuadsSerializer::new(out)),
"trig" => {
let config = TriGConfig::new().with_pretty(pretty);
let ser = TriGSerializer::new_with_config(out, config);
serialize_quads(quad_source, ser)
}
#[cfg(feature = "jsonld")]
"json-ld" | "jsonld" => serialize_quads(
quad_source,
JsonLdSerializer::new_with_options(out, JsonLdOptions::new().with_spaces(2)),
),
#[cfg(feature = "xml")]
"rdfxml" | "rdf" => {
let indent = if pretty { 4 } else { 0 };
let config = RdfXmlConfig::new().with_indentation(indent);
let ser = RdfXmlSerializer::new_with_config(out, config);
serialize_triples(quad_source, ser)
}
_ => {
eprintln!("Unrecognized format: {format}");
std::process::exit(-1);
}
};
if let Err(msg) = res {
eprintln!("{msg}");
std::process::exit(1);
}
}
fn serialize_triples<Q: QuadSource, S: TripleSerializer>(
quad_source: Q,
mut ser: S,
) -> Result<(), String> {
let triple_source = quad_source.filter_quads(|q| q.g().is_none()).to_triples();
match ser.serialize_triples(triple_source) {
Ok(_) => Ok(()),
Err(SourceError(e)) => Err(format!("Error while parsing input: {e}")),
Err(SinkError(e)) => Err(format!("Error while serializing triples: {e}")),
}
}
fn serialize_quads<Q: QuadSource, S: QuadSerializer>(
quad_source: Q,
mut ser: S,
) -> Result<(), String> {
match ser.serialize_quads(quad_source) {
Ok(_) => Ok(()),
Err(SourceError(e)) => Err(format!("Error while parsing input: {e}")),
Err(SinkError(e)) => Err(format!("Error while serializing quads: {e}")),
}
}