oxjelly 0.0.0

Parser and serializer for Jelly
Documentation
use std::collections::BTreeMap;
use std::io::Read;
use protobuf::Message;
use oxrdf::{GraphName, Literal, NamedNode, NamedOrBlankNode, Quad, Term};
use crate::{JellyParseError, JellySyntaxError};
use crate::jelly::rdf::{RdfIri, RdfStreamFrame};
use crate::jelly::rdf::rdf_literal::LiteralKind;
use crate::jelly::rdf::rdf_quad::{Graph, Object, Predicate, Subject};
use crate::jelly::rdf::rdf_stream_row::Row;

pub struct ReaderJellyParser<R: Read> {
    reader: R,
    prefix_map: BTreeMap<u32, String>,
    name_map: BTreeMap<u32, String>,
    datatype_map: BTreeMap<u32, String>,
    current_frame: Option<RdfStreamFrame>,
    current_row_index: usize,
    current_subject: Option<NamedOrBlankNode>,
    current_predicate: Option<NamedNode>,
    current_object: Option<Term>,
    current_graph: Option<GraphName>
}

impl<R: Read> ReaderJellyParser<R> {
    pub fn prefixes(&self) -> JellyPrefixesIter<'_> {
        todo!()
    }

    fn jelly_iri_to_named_node(&self, iri: &RdfIri) -> Result<NamedNode, JellySyntaxError> {
        let prefix = self.prefix_map
            .get(&iri.prefix_id)
            .map_or(Err(JellySyntaxError::PrefixIdNotFound(iri.prefix_id, iri.name_id)), Ok)?;

        let name = self.name_map
            .get(&iri.name_id)
            .map_or(Err(JellySyntaxError::NameIdNotFound(iri.prefix_id, iri.name_id)), Ok)?;

        let iri_str = format!("{prefix}{name}");
        Ok(NamedNode::new(iri_str)?)
    }

    fn jelly_subject_to_oxi_subject(&self, subject: Option<&Subject>) -> Result<NamedOrBlankNode, JellySyntaxError> {
        match subject {
            None => self.current_subject.clone().map_or(Err(JellySyntaxError::NoPreviousSubject), Ok),
            Some(Subject::SIri(iri)) => self.jelly_iri_to_named_node(iri).map(NamedOrBlankNode::NamedNode),
            _ => todo!(),
        }
    }

    fn jelly_predicate_to_oxi_predicate(&self, predicate: Option<&Predicate>) -> Result<NamedNode, JellySyntaxError> {
        match predicate {
            None => self.current_predicate.clone().map_or(Err(JellySyntaxError::NoPreviousPredicate), Ok),
            Some(Predicate::PIri(iri)) => self.jelly_iri_to_named_node(iri),
            _ => todo!(),
        }
    }

    fn jelly_object_to_oxi_object(&self, term: Option<&Object>) -> Result<Term, JellySyntaxError> {
        match term {
            None => self.current_object.clone().map_or(Err(JellySyntaxError::NoPreviousObject), Ok),
            Some(Object::OIri(iri)) => self.jelly_iri_to_named_node(iri).map(Term::NamedNode),
            Some(Object::OLiteral(literal)) => {
                match literal.literalKind.as_ref() {
                    Some(LiteralKind::Datatype(index)) => {
                        if let Some(datatype) = self.datatype_map.get(&index) {
                            let node = NamedNode::new_unchecked(datatype);
                            Ok(Term::Literal(Literal::new_typed_literal(literal.lex.clone(), node)))
                        } else {
                            Err(JellySyntaxError::DatatypeIdNotFound(*index))
                        }
                    }
                    Some(LiteralKind::Langtag(tag)) => {
                        Ok(Term::Literal(Literal::new_language_tagged_literal_unchecked(literal.lex.clone(), tag)))
                    }
                    None => Ok(Term::Literal(Literal::new_simple_literal(literal.lex.clone())))
                }
            }
            _ => todo!(),
        }
    }

    fn jelly_graph_name_to_oxi_graph_name(&self, term: Option<&Graph>) -> Result<GraphName, JellySyntaxError> {
        match term {
            None => self.current_graph.clone().map_or(Err(JellySyntaxError::NoPreviousGraphName), Ok),
            Some(Graph::GIri(iri)) => self.jelly_iri_to_named_node(iri).map(GraphName::NamedNode),
            Some(Graph::GDefaultGraph(_)) => Ok(GraphName::DefaultGraph),
            _ => {
                println!("{:?}", term);
                todo!()
            },
        }
    }
}

impl<R: Read> Iterator for ReaderJellyParser<R> {
    type Item = Result<Quad, JellyParseError>;

    fn next(&mut self) -> Option<Self::Item> {
        match &self.current_frame {
            Some(frame) => {
                loop {
                    match frame.rows.get(self.current_row_index) {
                        None => return None,
                        Some(row) => {
                            match &row.row {
                                Some(Row::Prefix(prefix)) => {
                                    self.prefix_map.insert(prefix.id, prefix.value.clone());
                                    self.current_row_index = self.current_row_index + 1;
                                }
                                Some(Row::Name(name)) => {
                                    println!("new name: {0}", name);
                                    self.name_map.insert(name.id, name.value.clone());
                                    self.current_row_index = self.current_row_index + 1;
                                }
                                Some(Row::Datatype(datatype)) => {
                                    self.datatype_map.insert(datatype.id, datatype.value.clone());
                                    self.current_row_index = self.current_row_index + 1;
                                }
                                Some(Row::Quad(quad)) => {
                                    let subject = self.jelly_subject_to_oxi_subject(quad.subject.as_ref());
                                    let predicate = self.jelly_predicate_to_oxi_predicate(quad.predicate.as_ref());
                                    let object = self.jelly_object_to_oxi_object(quad.object.as_ref());
                                    let graph_name = self.jelly_graph_name_to_oxi_graph_name(quad.graph.as_ref());
                                    return match (subject, predicate, object, graph_name) {
                                        (Err(err), _, _, _) => Some(Err(err.into())),
                                        (_, Err(err), _, _) => Some(Err(err.into())),
                                        (_, _, Err(err), _) => Some(Err(err.into())),
                                        (_, _, _, Err(err)) => Some(Err(err.into())),
                                        (Ok(subject), Ok(predicate), Ok(object), Ok(graph_name)) => {
                                            self.current_subject = Some(subject.clone());
                                            self.current_predicate = Some(predicate.clone());
                                            self.current_object = Some(object.clone());
                                            self.current_graph = Some(graph_name.clone());
                                            self.current_row_index = self.current_row_index + 1;
                                            Some(Ok(Quad::new(subject, predicate, object, graph_name)))
                                        }
                                    }
                                }
                                _ => self.current_row_index = self.current_row_index + 1
                            }
                        }
                    }
                }
            }
            None => {
                match RdfStreamFrame::parse_from_reader(&mut self.reader) {
                    Ok(frame) => {
                        self.current_frame = Some(frame);
                        self.current_row_index = 0;
                        self.current_subject = None;
                        self.current_predicate = None;
                        self.current_object = None;
                        self.current_graph = None;
                        self.next()
                    }
                    Err(err) => Some(
                        Err(JellyParseError::from(JellySyntaxError::from(err)))
                    )
                }
            }
        }
    }
}

pub struct JellyPrefixesIter<'a> {
    prefixes: std::collections::hash_map::Iter<'a, String, String>,
}

impl<'a> Iterator for JellyPrefixesIter<'a> {
    type Item = (&'a str, &'a str);
    fn next(&mut self) -> Option<Self::Item> {
        todo!()
    }
}

#[must_use]
pub struct SliceJellyParser<'a> {
    inner: &'a u64,
}

impl<'a> SliceJellyParser<'a> {
    pub fn prefixes(&self) -> JellyPrefixesIter<'_> {
        todo!()
    }
}

impl Iterator for SliceJellyParser<'_> {
    type Item = Result<Quad, JellySyntaxError>;

    fn next(&mut self) -> Option<Self::Item> {
        todo!()
    }
}

#[derive(Default, Clone)]
#[must_use]
pub struct JellyParser {}

impl JellyParser {
    #[inline]
    pub fn new() -> Self {
        Self {}
    }

    pub fn for_reader<R: Read>(self, reader: R) -> ReaderJellyParser<R> {
        ReaderJellyParser {
            reader,
            prefix_map: BTreeMap::new(),
            name_map: BTreeMap::new(),
            datatype_map: BTreeMap::new(),
            current_frame: None,
            current_row_index: 0,
            current_subject: None,
            current_predicate: None,
            current_object: None,
            current_graph: None,
        }
    }

    pub fn for_slice(self, slice: &(impl AsRef<[u8]> + ?Sized)) -> SliceJellyParser<'_> {
        todo!()
    }
}