Skip to content

Commit

Permalink
improve 'convert' example
Browse files Browse the repository at this point in the history
it can now convert between any two supported formats
  • Loading branch information
pchampin committed Feb 26, 2021
1 parent 017aab4 commit 0b449e7
Showing 1 changed file with 87 additions and 13 deletions.
100 changes: 87 additions & 13 deletions sophia/examples/convert.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,110 @@
//! Convert turtle on stdin into another format
//! Convert RDF on stdin from one format to another
use resiter::map::Map;
use sophia::serializer::TripleSerializer;
use sophia::triple::stream::TripleSource;
use sophia::term::{BoxTerm, CopyTerm};
use sophia::triple::{stream::TripleSource, Triple};
use std::convert::Infallible;
use std::io;
use std::iter::IntoIterator;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<_> = std::env::args().collect();
match args.get(1).map(String::as_str).unwrap_or("") {
if args.len() != 3 {
let message = if args.len() < 3 {
"too few arguments"
} else {
"too many arguments"
};
exit_printing_usage(&args, message, Status::ArgNumber);
}
match args[2].as_str() {
"nt" => {
let mut ser = sophia::serializer::nt::NtSerializer::new(io::stdout());
ser.serialize_triples(get_triples())?;
ser.serialize_triples(get_triples(&args))?;
}
"turtle" => {
let mut ser = sophia::serializer::turtle::TurtleSerializer::new(io::stdout());
ser.serialize_triples(get_triples())?;
ser.serialize_triples(get_triples(&args))?;
}
#[cfg(feature = "xml")]
"xml" => {
let mut ser = sophia::serializer::xml::RdfXmlSerializer::new(io::stdout());
ser.serialize_triples(get_triples())?;
ser.serialize_triples(get_triples(&args))?;
}
#[cfg(not(feature = "xml"))]
"xml" => {
exit_printing_usage(
&args,
"RDF/XML not supported (recompile with --feature xml)",
Status::UnsupportedXml,
);
}
_ => {
#[cfg(feature = "xml")]
eprintln!("usage: {} [nt|turtle|xml]", args[0]);
#[cfg(not(feature = "xml"))]
eprintln!("usage: {} [nt|turtle]", args[0]);
std::process::exit(1);
exit_printing_usage(&args, "unknown output format", Status::InputFormat);
}
}
Ok(())
}

fn get_triples() -> impl TripleSource {
fn get_triples(args: &[String]) -> MyTripleSource {
let bufread = io::BufReader::new(io::stdin());
sophia::parser::turtle::parse_bufread(bufread)
match args[1].as_str() {
"nt" => wrap(sophia::parser::nt::parse_bufread(bufread)),
"turtle" => wrap(sophia::parser::turtle::parse_bufread(bufread)),
#[cfg(feature = "xml")]
"xml" => wrap(sophia::parser::xml::parse_bufread(bufread)),
#[cfg(not(feature = "xml"))]
"xml" => {
exit_printing_usage(
&args,
"RDF/XML not supported (recompile with --feature xml)",
Status::UnsupportedXml,
);
}
_ => {
exit_printing_usage(&args, "unknown output format", Status::OutputFormat);
}
}
}

fn wrap<TS: TripleSource + 'static>(ts: TS) -> MyTripleSource {
Box::new(
ts.map_triples(|t| {
[
BoxTerm::copy(t.s()),
BoxTerm::copy(t.p()),
BoxTerm::copy(t.o()),
]
})
.into_iter()
.map_err(|e| {
eprintln!("error while parsing: {}", e);
std::process::exit(Status::ParseError as i32)
}),
)
}

type MyTripleSource = Box<dyn Iterator<Item = Result<[BoxTerm; 3], Infallible>>>;

fn exit_printing_usage(args: &[String], message: &str, status: Status) -> ! {
if message.len() > 0 {
eprintln!("{}", message);
}
eprintln!("usage: {} <format-in> <format-out>", args[0]);
eprintln!(" convert RDF on STDIN from one format to another,");
eprintln!(" where format can be:");
eprintln!(" - nt");
eprintln!(" - turtle");
#[cfg(feature = "xml")]
eprintln!(" - xml");
std::process::exit(status as i32)
}

enum Status {
ArgNumber = 1,
InputFormat = 2,
OutputFormat = 3,
ParseError = 4,
#[allow(dead_code)]
UnsupportedXml = 5,
}

0 comments on commit 0b449e7

Please sign in to comment.