1use std::{fmt::Display, ops::Range};
2
3use crate::Spanned;
4
5#[derive(Clone, Debug, PartialEq, Eq)]
6pub enum StringStyle {
7 DoubleLong,
8 Double,
9 SingleLong,
10 Single,
11}
12#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct Variable(pub String, pub usize);
14
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub enum Literal {
17 RDF(RDFLiteral),
18 Boolean(bool),
19 Numeric(String),
20}
21
22impl Literal {
23 pub fn plain_string(&self) -> String {
24 match self {
25 Literal::RDF(s) => s.plain_string(),
26 Literal::Boolean(x) => x.to_string(),
27 Literal::Numeric(x) => x.clone(),
28 }
29 }
30}
31impl Display for Literal {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 Literal::RDF(x) => x.fmt(f),
35 Literal::Boolean(x) => write!(f, "{}", x),
36 Literal::Numeric(x) => write!(f, "{}", x),
37 }
38 }
39}
40
41#[derive(Clone, Debug, PartialEq, Eq)]
42pub struct RDFLiteral {
43 pub value: String,
44 pub quote_style: StringStyle,
45 pub lang: Option<Spanned<String>>,
47 pub ty: Option<Spanned<NamedNode>>,
49 pub idx: usize,
51 pub len: usize,
52}
53
54impl RDFLiteral {
55 pub fn plain_string(&self) -> String {
56 self.value.to_string()
57 }
58}
59
60impl Display for RDFLiteral {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 let quote = match self.quote_style {
63 StringStyle::DoubleLong => "\"\"\"",
64 StringStyle::Double => "\"",
65 StringStyle::SingleLong => "'''",
66 StringStyle::Single => "'",
67 };
68 match (&self.lang, &self.ty) {
69 (None, None) => write!(f, "{}{}{}", quote, self.value, quote),
70 (None, Some(t)) => write!(f, "{}{}{}^^{}", quote, self.value, quote, t.value()),
71 (Some(l), None) => write!(f, "{}{}{}@{}", quote, self.value, quote, l.value()),
72 (Some(l), Some(t)) => {
73 write!(
74 f,
75 "{}{}{}@{}^^{}",
76 quote,
77 self.value,
78 quote,
79 l.value(),
80 t.value()
81 )
82 }
83 }
84 }
85}
86
87#[derive(Clone, Debug, PartialEq, Eq)]
88pub enum NamedNode {
89 Full(String, usize),
90 Prefixed {
91 prefix: String,
92 value: String,
93 idx: usize,
94 computed: Option<String>,
102 },
103 A(usize),
104 Invalid,
105}
106
107impl Display for NamedNode {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 match self {
110 NamedNode::Full(x, _) => write!(f, "<{}>", x),
111 NamedNode::Prefixed { prefix, value, .. } => {
112 if value.is_empty() && prefix.contains(':') {
116 write!(f, "{}", prefix)
117 } else {
118 write!(f, "{}:{}", prefix, value)
119 }
120 }
121 NamedNode::A(_) => write!(f, "a"),
122 NamedNode::Invalid => write!(f, "invalid"),
123 }
124 }
125}
126
127#[derive(Clone, Debug, PartialEq, Eq)]
128pub enum BlankNode {
129 Named(String, usize),
130 Unnamed(Vec<Spanned<PO>>, usize, usize),
131 Invalid,
132}
133
134impl Display for BlankNode {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 match self {
137 BlankNode::Named(x, _) => write!(f, "_:{}", x),
138 BlankNode::Unnamed(pos, _, _) => {
139 if pos.len() == 0 {
140 write!(f, "[ ]")
141 } else {
142 write!(f, "[ ")?;
143
144 for po in pos {
145 write!(f, "{} ;", po.value())?;
146 }
147
148 write!(f, " ]")
149 }
150 }
151 BlankNode::Invalid => write!(f, "invalid"),
152 }
153 }
154}
155
156#[derive(Clone, Debug, PartialEq, Eq)]
157pub enum Term {
158 Literal(Literal),
159 BlankNode(BlankNode),
160 NamedNode(NamedNode),
161 Collection(Vec<Spanned<Term>>),
162 Variable(Variable),
163 Invalid,
164}
165
166impl Term {
167 pub fn named_node(&self) -> Option<&NamedNode> {
168 match self {
169 Term::NamedNode(nn) => Some(&nn),
170 _ => None,
171 }
172 }
173
174 pub fn is_subject(&self) -> bool {
175 match self {
176 Term::BlankNode(_) => true,
177 Term::Variable(_) => true,
178 Term::NamedNode(NamedNode::A(_)) => false,
179 Term::NamedNode(_) => true,
180 Term::Invalid => true,
181 Term::Collection(_) => true,
182 _ => false,
183 }
184 }
185 pub fn is_predicate(&self) -> bool {
186 match self {
187 Term::NamedNode(_) => true,
188 Term::Variable(_) => true,
189 Term::Invalid => true,
190 _ => false,
191 }
192 }
193
194 pub fn is_object(&self) -> bool {
195 match self {
196 Term::NamedNode(NamedNode::A(_)) => false,
197 Term::Variable(_) => true,
198 Term::Invalid => true,
199 Term::Collection(_) => true,
200 _ => true,
201 }
202 }
203 pub fn is_variable(&self) -> bool {
204 match self {
205 Term::Variable(_) => true,
206 Term::Invalid => true,
207 _ => false,
208 }
209 }
210 pub fn ty(&self) -> &'static str {
211 match self {
212 Term::Literal(_) => "literal",
213 Term::BlankNode(_) => "blank node",
214 Term::NamedNode(_) => "named node",
215 Term::Collection(_) => "collection",
216 Term::Invalid => "invalid",
217 Term::Variable(_) => "variable",
218 }
219 }
220}
221
222impl Display for Term {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 match self {
225 Term::Literal(l) => l.fmt(f),
226 Term::BlankNode(b) => b.fmt(f),
227 Term::NamedNode(n) => n.fmt(f),
228 Term::Collection(n) => {
229 write!(f, "( ")?;
230 for l in n {
231 l.fmt(f)?;
232 }
233 write!(f, " )")?;
234 Ok(())
235 }
236 Term::Invalid => write!(f, "invalid"),
237 Term::Variable(x) => write!(f, "?{}", x.0),
238 }
239 }
240}
241
242#[derive(Clone, Debug, PartialEq, Eq)]
243pub struct Triple {
244 pub subject: Spanned<Term>,
245 pub po: Vec<Spanned<PO>>,
246 pub graph: Option<Spanned<Term>>,
247}
248
249impl Display for Triple {
250 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
251 if let Some(graph) = &self.graph {
252 write!(f, "GRAPH {} {{\n ", graph.value())?;
253 }
254
255 write!(f, "{}", self.subject.value())?;
256
257 if !self.po.is_empty() {
258 write!(f, " {}", self.po[0].value())?;
259 for po in &self.po[1..] {
260 if self.graph.is_some() {
261 write!(f, ";\n {}", po.value())?;
262 } else {
263 write!(f, ";\n {}", po.value())?;
264 }
265 }
266 }
267
268 write!(f, " .\n")?;
269
270 if self.graph.is_some() {
271 write!(f, "}}\n")?;
272 }
273
274 Ok(())
275 }
276}
277
278#[derive(Clone, Debug, PartialEq, Eq)]
279pub struct PO {
280 pub predicate: Spanned<Term>,
281 pub object: Vec<Spanned<Term>>,
282}
283
284impl Display for PO {
285 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 if let Some(o) = self.object.first() {
287 write!(f, "{} {}", self.predicate.value(), o.value())?;
288 } else {
289 write!(f, "{} undefined", self.predicate.value())?;
290 }
291
292 if self.object.len() > 1 {
293 for po in &self.object[1..] {
294 write!(f, ", {}", po.value())?;
295 }
296 }
297
298 Ok(())
299 }
300}
301
302#[derive(Clone, Debug, PartialEq, Eq)]
303pub struct Base(pub Range<usize>, pub Spanned<NamedNode>);
304impl Display for Base {
305 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
306 write!(f, "@base {} .", self.1.value())
307 }
308}
309
310#[derive(Clone, Debug, PartialEq, Eq)]
311pub struct TurtlePrefix {
312 pub span: Range<usize>,
313 pub prefix: Spanned<String>,
314 pub value: Spanned<NamedNode>,
315}
316
317impl Display for TurtlePrefix {
318 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
319 write!(
320 f,
321 "@prefix {}: {} .",
322 self.prefix.value(),
323 self.value.value()
324 )
325 }
326}
327
328#[derive(Debug)]
329pub enum TurtleSimpleError {
330 UnexpectedBase(&'static str),
331 UnexpectedBaseString(String),
332}
333
334#[derive(Clone, Debug, PartialEq, Eq)]
335pub struct Turtle {
336 pub base: Option<Spanned<Base>>,
337 pub prefixes: Vec<Spanned<TurtlePrefix>>,
338 pub triples: Vec<Spanned<Triple>>,
339 pub set_base: Option<String>,
342}
343
344impl Turtle {
345 pub fn empty() -> Self {
346 Self::new(None, Vec::new(), Vec::new())
347 }
348
349 pub fn new(
350 base: Option<Spanned<Base>>,
351 prefixes: Vec<Spanned<TurtlePrefix>>,
352 triples: Vec<Spanned<Triple>>,
353 ) -> Self {
354 Self {
355 base,
356 prefixes,
357 triples,
358 set_base: None,
359 }
360 }
361}
362
363impl Display for Turtle {
364 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
365 if let Some(b) = &self.base {
366 writeln!(f, "{}", b.value())?;
367 }
368
369 self.prefixes
370 .iter()
371 .map(|x| x.value())
372 .try_for_each(|x| writeln!(f, "{}", x))?;
373
374 self.triples
375 .iter()
376 .map(|x| x.value())
377 .try_for_each(|x| writeln!(f, "{}", x))?;
378
379 Ok(())
380 }
381}