1212//! - Allows specifying a custom RDF namespace for generated predicates and objects.
1313//! - Outputs the RDF data to a specified file or prints it to the console.
1414
15+ use clap:: Error ;
1516use oxrdf:: vocab:: xsd;
1617use oxrdf:: { BlankNode , Graph , Literal , NamedNodeRef , TripleRef } ;
1718
1819use serde_json:: { Deserializer , Value } ;
1920use std:: collections:: VecDeque ;
20- use std:: fs:: File ;
21+ use std:: fs:: { File , OpenOptions } ;
2122use std:: io:: { BufReader , Write } ;
2223
23- pub enum GraphOrMessage {
24- Graph ( Graph ) ,
25- Message ( String ) ,
26- }
27-
2824/// Converts JSON data to RDF format.
2925///
3026/// This function reads JSON data from the specified file, processes it into RDF triples,
@@ -47,7 +43,7 @@ pub fn json_to_rdf(
4743 file_path : & String ,
4844 namespace : & Option < String > ,
4945 output_file : & Option < String > ,
50- ) -> Result < GraphOrMessage , String > {
46+ ) -> Result < Option < Graph > , Error > {
5147 let rdf_namespace: String = if namespace. is_some ( ) {
5248 namespace. clone ( ) . unwrap ( )
5349 } else {
@@ -109,14 +105,16 @@ pub fn json_to_rdf(
109105 }
110106
111107 if let Some ( output_path) = output_file {
112- let mut file = File :: create ( output_path) . expect ( "Error creating file" ) ;
113- writeln ! ( file, "{}" , graph) . expect ( "Error writing to file" ) ;
114- Ok ( GraphOrMessage :: Message ( format ! (
115- "RDF created at: {}" ,
116- output_path
117- ) ) )
108+ let mut file = OpenOptions :: new ( )
109+ . create ( true )
110+ . append ( true )
111+ . open ( output_path)
112+ . expect ( "Error opening file" ) ;
113+
114+ writeln ! ( file, "{}" , graph) . expect ( "Error writing json2rdf data to file" ) ;
115+ Ok ( None )
118116 } else {
119- Ok ( GraphOrMessage :: Graph ( graph) )
117+ return Ok ( Some ( graph) ) ;
120118 }
121119}
122120
@@ -164,18 +162,21 @@ fn process_value(
164162 ) ) ;
165163 }
166164 Value :: Number ( num) => {
167- let literal = if let Some ( int) = num. as_i64 ( ) {
168- int. to_string ( )
169- } else if let Some ( float) = num. as_f64 ( ) {
170- float. to_string ( )
165+ if num. as_i64 ( ) . is_some ( ) {
166+ graph. insert ( TripleRef :: new (
167+ subject_stack. back ( ) . unwrap ( ) ,
168+ NamedNodeRef :: new ( prop. as_str ( ) ) . unwrap ( ) ,
169+ & Literal :: new_typed_literal ( num. to_string ( ) , xsd:: INT ) ,
170+ ) ) ;
171+ } else if num. as_f64 ( ) . is_some ( ) {
172+ graph. insert ( TripleRef :: new (
173+ subject_stack. back ( ) . unwrap ( ) ,
174+ NamedNodeRef :: new ( prop. as_str ( ) ) . unwrap ( ) ,
175+ & Literal :: new_typed_literal ( num. to_string ( ) , xsd:: FLOAT ) ,
176+ ) ) ;
171177 } else {
172178 return ;
173- } ;
174- graph. insert ( TripleRef :: new (
175- subject_stack. back ( ) . unwrap ( ) ,
176- NamedNodeRef :: new ( prop. as_str ( ) ) . unwrap ( ) ,
177- & Literal :: new_typed_literal ( literal, xsd:: INT ) ,
178- ) ) ;
179+ }
179180 }
180181 Value :: String ( s) => {
181182 graph. insert ( TripleRef :: new (
@@ -199,7 +200,7 @@ fn process_value(
199200
200201 for ( key, val) in obj {
201202 let nested_property: Option < String > =
202- Some ( format ! ( "{}/{}/ " , namespace, key) ) ;
203+ Some ( format ! ( "{}/{}" , namespace, key) ) ;
203204 process_value ( subject_stack, & nested_property, val, graph, namespace) ;
204205 }
205206 subject_stack. pop_back ( ) ;
0 commit comments