///|
/// 主语类型
pub(all) enum Subject {
Iri(ArrayView[Byte]) //
BNode(ArrayView[Byte]) // _:label
PrefName(ArrayView[Byte]) // ex:name 或 :name
} derive(Debug, Eq)
///|
/// 宾语类型
pub(all) enum Object {
Iri(ArrayView[Byte])
BNode(ArrayView[Byte])
Literal(ArrayView[Byte])
PrefName(ArrayView[Byte])
} derive(Debug, Eq)
///|
/// Predicate = BytesView(只能是 IRI)
pub type Predicate = ArrayView[Byte]
///|
/// 图名
pub(all) enum GraphName {
None // DefaultGraph
Iri(ArrayView[Byte])
} derive(Debug, Eq)
///|
/// N-Quads Quad
pub(all) struct QuadEmit {
subject : Subject
predicate : Predicate
object : Object
graph_name : GraphName
line : Int
} derive(Debug, Eq)
///|
pub impl Show for QuadEmit with fn output(self : QuadEmit, logger : &Logger) -> Unit {
logger.write_string("Quad(")
// 主语
match self.subject {
Subject::Iri(span) => {
logger.write_char('<')
logger.write_string("(\{span.length()})")
logger.write_char('>')
}
Subject::BNode(span) => {
logger.write_string("_:")
logger.write_string("(\{span.length()})")
}
Subject::PrefName(span) => logger.write_string("(\{span.length()})")
}
logger.write_string(", ")
// 谓语
logger.write_string("(\{self.predicate.length()})")
logger.write_string(", ")
// 宾语
match self.object {
Object::Iri(span) => {
logger.write_char('<')
logger.write_string("(\{span.length()})")
logger.write_char('>')
}
Object::BNode(span) => {
logger.write_string("_:")
logger.write_string("(\{span.length()})")
}
Object::Literal(span) | Object::PrefName(span) =>
logger.write_string("(\{span.length()})")
}
// 图名 ← 这里可能没有输出
match self.graph_name {
GraphName::None => logger.write_string(", graph: None")
GraphName::Iri(span) => {
logger.write_string(", graph: <")
logger.write_string("(\{span.length()})")
logger.write_char('>')
}
}
logger.write_char(')')
}
///|
pub impl Show for Subject with fn output(self : Subject, logger : &Logger) -> Unit {
match self {
Subject::Iri(span) => {
logger.write_char('<')
logger.write_string("(\{span.length()})")
logger.write_char('>')
}
Subject::BNode(span) => {
logger.write_string("_:")
logger.write_string("(\{span.length()})")
}
Subject::PrefName(span) => logger.write_string("(\{span.length()})")
}
}
///|
pub impl Show for Object with fn output(self : Object, logger : &Logger) -> Unit {
match self {
Object::Iri(span) => {
logger.write_char('<')
logger.write_string("(\{span.length()})")
logger.write_char('>')
}
Object::BNode(span) => {
logger.write_string("_:")
logger.write_string("(\{span.length()})")
}
Object::Literal(span) => logger.write_string("(\{span.length()})")
Object::PrefName(span) => logger.write_string("(\{span.length()})")
}
}
///|
pub struct Serializer {
data : ArrayView[Byte]
mode : StringView
}
///|
pub fn Serializer::new(
data : ArrayView[Byte],
mode? : StringView = "triple",
) -> Serializer {
{ data, mode }
}
///|
/// 序列化单个 Quad
pub fn Serializer::serialize(self : Serializer, quad : QuadEmit) -> String {
let buf = StringBuilder::new()
self.append_quad(quad, buf)
buf.to_string()
}
///|
fn Serializer::append_span(
_self : Serializer,
view : ArrayView[Byte],
buf : StringBuilder,
) -> Unit {
for b in view {
buf.write_char(b.to_char())
}
}
///|
/// 内联优化:主语序列化
fn Serializer::append_subject(
self : Serializer,
subject : Subject,
buf : StringBuilder,
) -> Unit {
match subject {
Subject::Iri(view) => self.append_span(view, buf)
Subject::BNode(view) => {
buf.write_string("_:")
// 跳过前两个字符 _:,直接写 label
let label = view[2:]
self.append_span(label, buf)
}
Subject::PrefName(view) => self.append_span(view, buf)
}
}
///|
/// 内联优化:宾语序列化
fn Serializer::append_object(
self : Serializer,
object : Object,
buf : StringBuilder,
) -> Unit {
match object {
Object::Iri(view) => self.append_span(view, buf)
Object::BNode(view) => {
buf.write_string("_:")
let label = view[2:]
self.append_span(label, buf)
}
Object::Literal(view) => self.append_span(view, buf)
Object::PrefName(view) => self.append_span(view, buf)
}
}
///|
/// 优化后的 Quad 序列化
fn Serializer::append_quad(
self : Serializer,
quad : QuadEmit,
buf : StringBuilder,
) -> Unit {
// 主语
self.append_subject(quad.subject, buf)
buf.write_char(' ')
// 谓语
self.append_span(quad.predicate, buf)
buf.write_char(' ')
// 宾语
self.append_object(quad.object, buf)
// 图名
match quad.graph_name {
GraphName::Iri(view) => {
buf.write_char(' ')
self.append_span(view, buf)
}
GraphName::None => ()
}
buf.write_string(" .\n")
}
///|
/// 序列化三元组(忽略图名)
fn Serializer::append_triple(
self : Serializer,
quad : QuadEmit,
buf : StringBuilder,
) -> Unit {
self.append_subject(quad.subject, buf)
buf.write_char(' ')
self.append_span(quad.predicate, buf)
buf.write_char(' ')
self.append_object(quad.object, buf)
buf.write_string(" .\n")
}
///|
pub fn Serializer::serialize_all(
self : Serializer,
quads : Array[QuadEmit],
) -> String {
let buf = StringBuilder::new()
for quad in quads {
lexscan self.mode with longest {
// 三元组模式
re"^(?i:triple)$" => self.append_triple(quad, buf)
// 四元组模式(包含图名)
re"^(?i:quad|quads|all)$" => self.append_quad(quad, buf)
// 只输出有图名的四元组
re"^(?i:quadonly)$" =>
match quad.graph_name {
GraphName::Iri(_) => self.append_quad(quad, buf)
GraphName::None => ()
}
// 默认三元组
_ => self.append_triple(quad, buf)
}
}
buf.to_string()
}