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
//! API for serializing RDF syntaxes.
//!
//! This module specifies, through dedicated traits,
//! how serialization of triples/graphs and quads/dataset is handled in sophia.
//! These traits are designed with the idea that each serializer has a specific
//! “target” (typically a file or something similar)
//! associated to it.
//! If you want to serialize to two different files,
//! you must create two different serializers.
//!
//! Note however that this API does not cover the creation of serializers,
//! and therefore does not cover how their target is specified.

use crate::dataset::*;
use crate::graph::*;
use crate::quad::stream::*;
use crate::triple::stream::*;

/// A triple serializer writes triples according to a given format.
pub trait TripleSerializer {
    type Error: 'static + std::error::Error;

    /// Serialize all triples from the given [`TripleSource`].
    fn serialize_triples<TS>(
        &mut self,
        source: TS,
    ) -> StreamResult<&mut Self, TS::Error, Self::Error>
    where
        TS: TripleSource,
        Self: Sized;

    /// Serialize a whole [`Graph`].
    ///
    /// While this method has a default implementation based on
    /// [`serialize_triples`](Self::serialize_triples),
    /// some implementations may override it in order to better use the structure of the Graph.
    #[inline]
    fn serialize_graph<G>(&mut self, graph: &G) -> StreamResult<&mut Self, G::Error, Self::Error>
    where
        G: Graph,
        Self: Sized,
    {
        self.serialize_triples(&mut graph.triples())
    }
}

/// A quad serializer writes quads according to a given format.
pub trait QuadSerializer {
    type Error: 'static + std::error::Error;

    /// Serialize all quads from the given [`QuadSource`].
    fn serialize_quads<QS>(
        &mut self,
        source: QS,
    ) -> StreamResult<&mut Self, QS::Error, Self::Error>
    where
        QS: QuadSource,
        Self: Sized;

    /// Serialize a whole [`Dataset`].
    ///
    /// While this method has a default implementation based on
    /// [`serialize_quads`](Self::serialize_quads),
    /// some implementations may override it in order to better use the structure of the Dataset.
    #[inline]
    fn serialize_dataset<D>(
        &mut self,
        dataset: &D,
    ) -> StreamResult<&mut Self, D::Error, Self::Error>
    where
        D: Dataset,
        Self: Sized,
    {
        self.serialize_quads(&mut dataset.quads())
    }
}

/// A stringifier is special kind of [`TripleSerializer`] or [`QuadSerializer`]:
///
/// + it uses a text-based format encoded in UTF8;
/// + it stores the serialize data in memory;
/// + it gives access to the serialized data as `str` or `String`.
///
/// [`TripleSerializer`]: trait.TripleSerializer.html
/// [`QuadSerializer`]: trait.QuadSerializer.html
pub trait Stringifier {
    /// Borrows the internal serialized data.
    ///
    /// # Safety
    /// It is the responsibility of implementors to ensure that this data is valid UTF8.
    /// The methods [`as_str`](#method.as_str) and
    /// [`to_string`](#method.to_string) rely on this.
    fn as_utf8(&self) -> &[u8];

    /// Borrows the internal serialized data as a `str`.
    fn as_str(&self) -> &str {
        unsafe { std::str::from_utf8_unchecked(self.as_utf8()) }
    }

    /// Copy the internal serialized data to a `String`.
    fn to_string(&self) -> String {
        self.as_str().to_string()
    }
}