1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
use writer::formatter::rdf_formatter::*; use writer::formatter::n_triples_formatter::NTriplesFormatter; use writer::rdf_writer::RdfWriter; use graph::Graph; use node::Node; use triple::*; use error::*; use Result; /// RDF writer to generate N-Triples syntax. #[derive(Default)] pub struct NTriplesWriter { formatter: NTriplesFormatter, } impl RdfWriter for NTriplesWriter { /// Generates the N-Triples syntax for each triple stored in the provided graph. /// /// Returns an error if invalid N-Triple syntax would be generated. /// /// # Examples /// /// ``` /// use rdf::writer::n_triples_writer::NTriplesWriter; /// use rdf::writer::rdf_writer::RdfWriter; /// use rdf::graph::Graph; /// /// let writer = NTriplesWriter::new(); /// let graph = Graph::new(None); /// /// assert_eq!(writer.write_to_string(&graph).unwrap(), "".to_string()); /// ``` /// /// # Failures /// /// - Invalid triples are to be written to the output that do not conform the NTriples syntax standard. /// fn write_to_string(&self, graph: &Graph) -> Result<String> { let mut output_string = "".to_string(); for triple in graph.triples_iter() { // convert each triple of the graph to N-Triple syntax match self.triple_to_n_triples(triple) { Ok(str) => { output_string.push_str(&str); output_string.push_str("\n"); } Err(error) => return Err(error), } } Ok(output_string) } } impl NTriplesWriter { /// Constructor of `NTriplesWriter`. /// /// # Examples /// /// ``` /// use rdf::writer::n_triples_writer::NTriplesWriter; /// use rdf::writer::rdf_writer::RdfWriter; /// /// let writer = NTriplesWriter::new(); /// ``` pub fn new() -> NTriplesWriter { NTriplesWriter { formatter: NTriplesFormatter::new(), } } /// Generates the corresponding N-Triples syntax of the provided triple. /// /// # Examples /// /// ``` /// use rdf::writer::n_triples_writer::NTriplesWriter; /// use rdf::writer::rdf_writer::RdfWriter; /// use rdf::node::Node; /// use rdf::triple::Triple; /// use rdf::uri::Uri; /// /// let writer = NTriplesWriter::new(); /// /// let subject = Node::BlankNode { id: "blank".to_string() }; /// let object = Node::LiteralNode { literal: "literal".to_string(), data_type: None, language: Some("en".to_string()) }; /// let predicate = Node::UriNode { uri: Uri::new("http://example.org/show/localName".to_string()) }; /// let triple = Triple::new(&subject, &predicate, &object); /// /// assert_eq!(writer.triple_to_n_triples(&triple).unwrap(), /// "_:blank <http://example.org/show/localName> \"literal\"@en .".to_string()); /// ``` /// /// # Failures /// /// - Invalid node type for a certain position. /// pub fn triple_to_n_triples(&self, triple: &Triple) -> Result<String> { let mut output_string = "".to_string(); // convert subject match self.node_to_n_triples(triple.subject(), &TripleSegment::Subject) { Ok(str) => output_string.push_str(&str), Err(error) => return Err(error), } output_string.push_str(" "); // convert predicate match self.node_to_n_triples(triple.predicate(), &TripleSegment::Predicate) { Ok(str) => output_string.push_str(&str), Err(error) => return Err(error), } output_string.push_str(" "); // convert object match self.node_to_n_triples(triple.object(), &TripleSegment::Object) { Ok(str) => output_string.push_str(&str), Err(error) => return Err(error), } output_string.push_str(" ."); Ok(output_string) } /// Converts a single node to its corresponding N-Triples representation. /// /// Checks if the node type is valid considering the triple segment. /// /// # Examples /// /// ``` /// use rdf::writer::n_triples_writer::NTriplesWriter; /// use rdf::writer::rdf_writer::RdfWriter; /// use rdf::node::Node; /// use rdf::triple::TripleSegment; /// /// let writer = NTriplesWriter::new(); /// /// let node = Node::BlankNode { id: "blank".to_string() }; /// /// assert_eq!(writer.node_to_n_triples(&node, &TripleSegment::Subject).unwrap(), /// "_:blank".to_string()); /// ``` /// /// # Failures /// /// - Node type for triple segment does not conform with NTriples syntax standard. /// pub fn node_to_n_triples(&self, node: &Node, segment: &TripleSegment) -> Result<String> { match *node { Node::BlankNode { .. } => // blank nodes are not allowed as predicates if *segment == TripleSegment::Predicate { return Err(Error::new(ErrorType::InvalidWriterOutput, "Blank nodes are not allowed as predicates.")) }, Node::LiteralNode { data_type: ref dt, language: ref lang, .. } => { // literal nodes are only allowed as objects if *segment != TripleSegment::Object { return Err(Error::new(ErrorType::InvalidWriterOutput, "Literals are not allowed as subjects or predicates.")) } // either language or data type could be defined, but not both if *lang != None && *dt != None { return Err(Error::new(ErrorType::InvalidWriterOutput, "Language and data type defined for a literal.")) } }, _ => {}, } // use the formatter to get the corresponding N-Triple syntax Ok(self.formatter.format_node(node)) } }