rdf_types/pattern/triple/
canonical.rs

1use replace_with::replace_with_or_abort_and_return;
2
3use crate::{
4	pattern::{quad, CanonicalQuadPattern, ResourceOrVar, TriplePattern},
5	Triple,
6};
7
8/// Canonical triple pattern.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub enum CanonicalTriplePattern<T> {
11	AnySubject(AnySubject<T>),
12	GivenSubject(T, GivenSubject<T>),
13}
14
15impl<T> From<Triple<T>> for CanonicalTriplePattern<T> {
16	fn from(value: Triple<T>) -> Self {
17		Self::from_triple(value)
18	}
19}
20
21impl<T> From<Triple<Option<T>, Option<T>, Option<T>>> for CanonicalTriplePattern<T> {
22	fn from(value: Triple<Option<T>, Option<T>, Option<T>>) -> Self {
23		Self::from_option_triple(value)
24	}
25}
26
27impl<T, X: PartialEq> From<TriplePattern<T, X>> for CanonicalTriplePattern<T> {
28	fn from(value: TriplePattern<T, X>) -> Self {
29		Self::from_pattern(value)
30	}
31}
32
33impl<T> CanonicalTriplePattern<T> {
34	pub fn from_triple(triple: Triple<T>) -> Self {
35		Self::GivenSubject(
36			triple.0,
37			GivenSubject::GivenPredicate(
38				triple.1,
39				GivenSubjectGivenPredicate::GivenObject(triple.2),
40			),
41		)
42	}
43
44	pub fn from_option_triple(triple: Triple<Option<T>, Option<T>, Option<T>>) -> Self {
45		match triple.0 {
46			Some(s) => Self::GivenSubject(s, GivenSubject::from_option_triple(triple.1, triple.2)),
47			None => Self::AnySubject(AnySubject::from_option_triple(triple.1, triple.2)),
48		}
49	}
50
51	pub fn from_pattern<X: PartialEq>(pattern: TriplePattern<T, X>) -> Self {
52		match pattern.0 {
53			ResourceOrVar::Resource(s) => {
54				Self::GivenSubject(s, GivenSubject::from_pattern(pattern.1, pattern.2))
55			}
56			ResourceOrVar::Var(s) => {
57				Self::AnySubject(AnySubject::from_pattern(s, pattern.1, pattern.2))
58			}
59		}
60	}
61
62	pub fn with_any_graph(self) -> CanonicalQuadPattern<T> {
63		match self {
64			Self::AnySubject(p) => CanonicalQuadPattern::AnySubject(p.with_any_graph()),
65			Self::GivenSubject(id, p) => CanonicalQuadPattern::GivenSubject(id, p.with_any_graph()),
66		}
67	}
68
69	pub fn subject(&self) -> PatternSubject<&T> {
70		match self {
71			Self::AnySubject(_) => PatternSubject::Any,
72			Self::GivenSubject(id, _) => PatternSubject::Given(id),
73		}
74	}
75
76	pub fn into_subject(self) -> PatternSubject<T> {
77		match self {
78			Self::AnySubject(_) => PatternSubject::Any,
79			Self::GivenSubject(id, _) => PatternSubject::Given(id),
80		}
81	}
82
83	pub fn predicate(&self) -> PatternPredicate<&T> {
84		match self {
85			Self::AnySubject(t) => t.predicate(),
86			Self::GivenSubject(_, t) => t.predicate(),
87		}
88	}
89
90	pub fn into_predicate(self) -> PatternPredicate<T> {
91		match self {
92			Self::AnySubject(t) => t.into_predicate(),
93			Self::GivenSubject(_, t) => t.into_predicate(),
94		}
95	}
96
97	pub fn object(&self) -> PatternObject<&T> {
98		match self {
99			Self::AnySubject(t) => t.object(),
100			Self::GivenSubject(_, t) => t.object(),
101		}
102	}
103
104	pub fn into_object(self) -> PatternObject<T> {
105		match self {
106			Self::AnySubject(t) => t.into_object(),
107			Self::GivenSubject(_, t) => t.into_object(),
108		}
109	}
110
111	pub fn set_subject(&mut self, s: T) -> PatternSubject<T>
112	where
113		T: Clone,
114	{
115		replace_with_or_abort_and_return(self, |this| match this {
116			Self::AnySubject(AnySubject::AnyPredicate(AnySubjectAnyPredicate::AnyObject)) => (
117				PatternSubject::Any,
118				Self::GivenSubject(
119					s,
120					GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::AnyObject),
121				),
122			),
123			Self::AnySubject(AnySubject::AnyPredicate(AnySubjectAnyPredicate::SameAsSubject)) => (
124				PatternSubject::Any,
125				Self::GivenSubject(
126					s.clone(),
127					GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::GivenObject(s)),
128				),
129			),
130			Self::AnySubject(AnySubject::AnyPredicate(AnySubjectAnyPredicate::SameAsPredicate)) => {
131				(
132					PatternSubject::Any,
133					Self::GivenSubject(
134						s,
135						GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::SameAsPredicate),
136					),
137				)
138			}
139			Self::AnySubject(AnySubject::AnyPredicate(AnySubjectAnyPredicate::GivenObject(o))) => (
140				PatternSubject::Any,
141				Self::GivenSubject(
142					s,
143					GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::GivenObject(o)),
144				),
145			),
146			Self::AnySubject(AnySubject::SameAsSubject(AnySubjectGivenPredicate::AnyObject)) => (
147				PatternSubject::Any,
148				Self::GivenSubject(
149					s.clone(),
150					GivenSubject::GivenPredicate(s, GivenSubjectGivenPredicate::AnyObject),
151				),
152			),
153			Self::AnySubject(AnySubject::SameAsSubject(
154				AnySubjectGivenPredicate::SameAsSubject,
155			)) => (
156				PatternSubject::Any,
157				Self::GivenSubject(
158					s.clone(),
159					GivenSubject::GivenPredicate(
160						s.clone(),
161						GivenSubjectGivenPredicate::GivenObject(s),
162					),
163				),
164			),
165			Self::AnySubject(AnySubject::SameAsSubject(AnySubjectGivenPredicate::GivenObject(
166				o,
167			))) => (
168				PatternSubject::Any,
169				Self::GivenSubject(
170					s.clone(),
171					GivenSubject::GivenPredicate(s, GivenSubjectGivenPredicate::GivenObject(o)),
172				),
173			),
174			Self::AnySubject(AnySubject::GivenPredicate(
175				p,
176				AnySubjectGivenPredicate::AnyObject,
177			)) => (
178				PatternSubject::Any,
179				Self::GivenSubject(
180					s,
181					GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::AnyObject),
182				),
183			),
184			Self::AnySubject(AnySubject::GivenPredicate(
185				p,
186				AnySubjectGivenPredicate::SameAsSubject,
187			)) => (
188				PatternSubject::Any,
189				Self::GivenSubject(
190					s.clone(),
191					GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::GivenObject(s)),
192				),
193			),
194			Self::AnySubject(AnySubject::GivenPredicate(
195				p,
196				AnySubjectGivenPredicate::GivenObject(o),
197			)) => (
198				PatternSubject::Any,
199				Self::GivenSubject(
200					s,
201					GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::GivenObject(o)),
202				),
203			),
204			Self::GivenSubject(
205				current_s,
206				GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::AnyObject),
207			) => (
208				PatternSubject::Given(current_s),
209				Self::GivenSubject(
210					s,
211					GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::AnyObject),
212				),
213			),
214			Self::GivenSubject(
215				current_s,
216				GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::SameAsPredicate),
217			) => (
218				PatternSubject::Given(current_s),
219				Self::GivenSubject(
220					s,
221					GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::SameAsPredicate),
222				),
223			),
224			Self::GivenSubject(
225				current_s,
226				GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::GivenObject(o)),
227			) => (
228				PatternSubject::Given(current_s),
229				Self::GivenSubject(
230					s,
231					GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::GivenObject(o)),
232				),
233			),
234			Self::GivenSubject(
235				current_s,
236				GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::AnyObject),
237			) => (
238				PatternSubject::Given(current_s),
239				Self::GivenSubject(
240					s,
241					GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::AnyObject),
242				),
243			),
244			Self::GivenSubject(
245				current_s,
246				GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::GivenObject(o)),
247			) => (
248				PatternSubject::Given(current_s),
249				Self::GivenSubject(
250					s,
251					GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::GivenObject(o)),
252				),
253			),
254		})
255	}
256
257	pub fn with_subject(mut self, s: T) -> Self
258	where
259		T: Clone,
260	{
261		self.set_subject(s);
262		self
263	}
264
265	pub fn set_predicate(&mut self, p: T) -> PatternPredicate<T>
266	where
267		T: Clone,
268	{
269		replace_with_or_abort_and_return(self, |this| match this {
270			Self::AnySubject(AnySubject::SameAsSubject(AnySubjectGivenPredicate::AnyObject)) => (
271				PatternPredicate::SameAsSubject,
272				Self::GivenSubject(
273					p.clone(),
274					GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::AnyObject),
275				),
276			),
277			Self::AnySubject(AnySubject::SameAsSubject(
278				AnySubjectGivenPredicate::SameAsSubject,
279			)) => (
280				PatternPredicate::SameAsSubject,
281				Self::GivenSubject(
282					p.clone(),
283					GivenSubject::GivenPredicate(
284						p.clone(),
285						GivenSubjectGivenPredicate::GivenObject(p),
286					),
287				),
288			),
289			Self::AnySubject(AnySubject::SameAsSubject(AnySubjectGivenPredicate::GivenObject(
290				o,
291			))) => (
292				PatternPredicate::SameAsSubject,
293				Self::GivenSubject(
294					p.clone(),
295					GivenSubject::GivenPredicate(p, GivenSubjectGivenPredicate::GivenObject(o)),
296				),
297			),
298			Self::AnySubject(mut current_p) => {
299				let old_p = current_p.set_predicate(p);
300				(old_p, Self::AnySubject(current_p))
301			}
302			Self::GivenSubject(s, mut current_p) => {
303				let old_p = current_p.set_predicate(p);
304				(old_p, Self::GivenSubject(s, current_p))
305			}
306		})
307	}
308
309	pub fn with_predicate(mut self, p: T) -> Self
310	where
311		T: Clone,
312	{
313		self.set_predicate(p);
314		self
315	}
316
317	pub fn set_object(&mut self, o: T) -> PatternObject<T>
318	where
319		T: Clone,
320	{
321		replace_with_or_abort_and_return(self, |this| match this {
322			Self::AnySubject(AnySubject::AnyPredicate(AnySubjectAnyPredicate::SameAsSubject)) => (
323				PatternObject::SameAsSubject,
324				Self::GivenSubject(
325					o.clone(),
326					GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::GivenObject(o)),
327				),
328			),
329			Self::AnySubject(AnySubject::SameAsSubject(
330				AnySubjectGivenPredicate::SameAsSubject,
331			)) => (
332				PatternObject::SameAsSubject,
333				Self::GivenSubject(
334					o.clone(),
335					GivenSubject::GivenPredicate(
336						o.clone(),
337						GivenSubjectGivenPredicate::GivenObject(o),
338					),
339				),
340			),
341			Self::AnySubject(mut current_p) => {
342				let old_p = current_p.set_object(o);
343				(old_p, Self::AnySubject(current_p))
344			}
345			Self::GivenSubject(s, mut current_p) => {
346				let old_p = current_p.set_object(o);
347				(old_p, Self::GivenSubject(s, current_p))
348			}
349		})
350	}
351
352	pub fn with_object(mut self, o: T) -> Self
353	where
354		T: Clone,
355	{
356		self.set_object(o);
357		self
358	}
359}
360
361#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
362pub enum PatternSubject<T> {
363	Any,
364	Given(T),
365}
366
367impl<T> PatternSubject<T> {
368	pub fn id(&self) -> Option<&T> {
369		match self {
370			Self::Any => None,
371			Self::Given(id) => Some(id),
372		}
373	}
374
375	pub fn into_id(self) -> Option<T> {
376		match self {
377			Self::Any => None,
378			Self::Given(id) => Some(id),
379		}
380	}
381}
382
383impl<T> PatternSubject<&T> {
384	pub fn cloned(self) -> PatternSubject<T>
385	where
386		T: Clone,
387	{
388		match self {
389			Self::Any => PatternSubject::Any,
390			Self::Given(t) => PatternSubject::Given(t.clone()),
391		}
392	}
393}
394
395#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
396pub enum PatternPredicate<T> {
397	Any,
398	SameAsSubject,
399	Given(T),
400}
401
402impl<T> PatternPredicate<T> {
403	pub fn id(&self) -> Option<&T> {
404		match self {
405			Self::Any => None,
406			Self::SameAsSubject => None,
407			Self::Given(id) => Some(id),
408		}
409	}
410
411	pub fn into_id(self) -> Option<T> {
412		match self {
413			Self::Any => None,
414			Self::SameAsSubject => None,
415			Self::Given(id) => Some(id),
416		}
417	}
418}
419
420impl<T> PatternPredicate<&T> {
421	pub fn cloned(self) -> PatternPredicate<T>
422	where
423		T: Clone,
424	{
425		match self {
426			Self::Any => PatternPredicate::Any,
427			Self::SameAsSubject => PatternPredicate::SameAsSubject,
428			Self::Given(t) => PatternPredicate::Given(t.clone()),
429		}
430	}
431}
432
433#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
434pub enum PatternObject<T> {
435	Any,
436	SameAsSubject,
437	SameAsPredicate,
438	Given(T),
439}
440
441impl<T> PatternObject<T> {
442	pub fn id(&self) -> Option<&T> {
443		match self {
444			Self::Given(id) => Some(id),
445			_ => None,
446		}
447	}
448
449	pub fn into_id(self) -> Option<T> {
450		match self {
451			Self::Given(id) => Some(id),
452			_ => None,
453		}
454	}
455}
456
457impl<T> PatternObject<&T> {
458	pub fn cloned(self) -> PatternObject<T>
459	where
460		T: Clone,
461	{
462		match self {
463			Self::Any => PatternObject::Any,
464			Self::SameAsSubject => PatternObject::SameAsSubject,
465			Self::SameAsPredicate => PatternObject::SameAsPredicate,
466			Self::Given(t) => PatternObject::Given(t.clone()),
467		}
468	}
469}
470
471impl<T: PartialEq> PatternObject<T> {
472	pub fn filter_triple(&self, triple: Triple<T>) -> bool {
473		match self {
474			Self::Any => true,
475			Self::SameAsSubject => triple.2 == triple.0,
476			Self::SameAsPredicate => triple.2 == triple.1,
477			Self::Given(id) => triple.2 == *id,
478		}
479	}
480}
481
482#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
483pub enum AnySubject<T> {
484	AnyPredicate(AnySubjectAnyPredicate<T>),
485	SameAsSubject(AnySubjectGivenPredicate<T>),
486	GivenPredicate(T, AnySubjectGivenPredicate<T>),
487}
488
489impl<T> AnySubject<T> {
490	pub fn from_option_triple(p: Option<T>, o: Option<T>) -> Self {
491		match p {
492			Some(p) => Self::GivenPredicate(p, AnySubjectGivenPredicate::from_option(o)),
493			None => Self::AnyPredicate(AnySubjectAnyPredicate::from_option(o)),
494		}
495	}
496
497	pub fn from_pattern<X: PartialEq>(
498		s: X,
499		p: ResourceOrVar<T, X>,
500		o: ResourceOrVar<T, X>,
501	) -> Self {
502		match p {
503			ResourceOrVar::Resource(p) => {
504				Self::GivenPredicate(p, AnySubjectGivenPredicate::from_pattern(s, o))
505			}
506			ResourceOrVar::Var(p) => {
507				if p == s {
508					Self::SameAsSubject(AnySubjectGivenPredicate::from_pattern(s, o))
509				} else {
510					Self::AnyPredicate(AnySubjectAnyPredicate::from_pattern(s, p, o))
511				}
512			}
513		}
514	}
515
516	pub fn with_any_graph(self) -> quad::canonical::AnySubject<T> {
517		match self {
518			Self::AnyPredicate(o) => quad::canonical::AnySubject::AnyPredicate(o.with_any_graph()),
519			Self::SameAsSubject(o) => {
520				quad::canonical::AnySubject::SameAsSubject(o.with_any_graph())
521			}
522			Self::GivenPredicate(id, o) => {
523				quad::canonical::AnySubject::GivenPredicate(id, o.with_any_graph())
524			}
525		}
526	}
527
528	pub fn predicate(&self) -> PatternPredicate<&T> {
529		match self {
530			Self::AnyPredicate(_) => PatternPredicate::Any,
531			Self::SameAsSubject(_) => PatternPredicate::SameAsSubject,
532			Self::GivenPredicate(id, _) => PatternPredicate::Given(id),
533		}
534	}
535
536	pub fn into_predicate(self) -> PatternPredicate<T> {
537		match self {
538			Self::AnyPredicate(_) => PatternPredicate::Any,
539			Self::SameAsSubject(_) => PatternPredicate::SameAsSubject,
540			Self::GivenPredicate(id, _) => PatternPredicate::Given(id),
541		}
542	}
543
544	pub fn object(&self) -> PatternObject<&T> {
545		match self {
546			Self::AnyPredicate(t) => t.object(),
547			Self::SameAsSubject(t) => t.object(),
548			Self::GivenPredicate(_, t) => t.object(),
549		}
550	}
551
552	pub fn into_object(self) -> PatternObject<T> {
553		match self {
554			Self::AnyPredicate(t) => t.into_object(),
555			Self::SameAsSubject(t) => t.into_object(),
556			Self::GivenPredicate(_, t) => t.into_object(),
557		}
558	}
559
560	pub fn set_predicate(&mut self, p: T) -> PatternPredicate<T>
561	where
562		T: Clone,
563	{
564		replace_with_or_abort_and_return(self, |this| match this {
565			Self::AnyPredicate(AnySubjectAnyPredicate::AnyObject) => (
566				PatternPredicate::Any,
567				Self::GivenPredicate(p, AnySubjectGivenPredicate::AnyObject),
568			),
569			Self::AnyPredicate(AnySubjectAnyPredicate::SameAsSubject) => (
570				PatternPredicate::Any,
571				Self::GivenPredicate(p, AnySubjectGivenPredicate::AnyObject),
572			),
573			Self::AnyPredicate(AnySubjectAnyPredicate::SameAsPredicate) => (
574				PatternPredicate::Any,
575				Self::GivenPredicate(p.clone(), AnySubjectGivenPredicate::GivenObject(p)),
576			),
577			Self::AnyPredicate(AnySubjectAnyPredicate::GivenObject(o)) => (
578				PatternPredicate::Any,
579				Self::GivenPredicate(p, AnySubjectGivenPredicate::GivenObject(o)),
580			),
581			Self::SameAsSubject(AnySubjectGivenPredicate::AnyObject) => (
582				PatternPredicate::SameAsSubject,
583				Self::GivenPredicate(p, AnySubjectGivenPredicate::AnyObject),
584			),
585			Self::SameAsSubject(AnySubjectGivenPredicate::SameAsSubject) => (
586				PatternPredicate::SameAsSubject,
587				Self::GivenPredicate(p.clone(), AnySubjectGivenPredicate::GivenObject(p)),
588			),
589			Self::SameAsSubject(AnySubjectGivenPredicate::GivenObject(o)) => (
590				PatternPredicate::SameAsSubject,
591				Self::GivenPredicate(p, AnySubjectGivenPredicate::GivenObject(o)),
592			),
593			Self::GivenPredicate(current_p, o) => (
594				PatternPredicate::Given(current_p),
595				Self::GivenPredicate(p, o),
596			),
597		})
598	}
599
600	pub fn set_object(&mut self, o: T) -> PatternObject<T>
601	where
602		T: Clone,
603	{
604		replace_with_or_abort_and_return(self, |this| match this {
605			Self::AnyPredicate(AnySubjectAnyPredicate::SameAsPredicate) => (
606				PatternObject::Any,
607				Self::GivenPredicate(o.clone(), AnySubjectGivenPredicate::GivenObject(o)),
608			),
609			Self::AnyPredicate(mut current_o) => {
610				let old_o = current_o.set_object(o);
611				(old_o, Self::AnyPredicate(current_o))
612			}
613			Self::SameAsSubject(AnySubjectGivenPredicate::SameAsSubject) => (
614				PatternObject::SameAsSubject,
615				Self::GivenPredicate(o.clone(), AnySubjectGivenPredicate::GivenObject(o)),
616			),
617			Self::SameAsSubject(mut current_o) => {
618				let old_o = current_o.set_object(o);
619				(old_o, Self::SameAsSubject(current_o))
620			}
621			Self::GivenPredicate(p, mut current_o) => {
622				let old_o = current_o.set_object(o);
623				(old_o, Self::GivenPredicate(p, current_o))
624			}
625		})
626	}
627}
628
629#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
630pub enum AnySubjectAnyPredicate<T> {
631	AnyObject,
632	SameAsSubject,
633	SameAsPredicate,
634	GivenObject(T),
635}
636
637impl<T> AnySubjectAnyPredicate<T> {
638	pub fn from_option(o: Option<T>) -> Self {
639		match o {
640			Some(o) => Self::GivenObject(o),
641			None => Self::AnyObject,
642		}
643	}
644
645	pub fn from_pattern<X: PartialEq>(s: X, p: X, o: ResourceOrVar<T, X>) -> Self {
646		match o {
647			ResourceOrVar::Resource(o) => Self::GivenObject(o),
648			ResourceOrVar::Var(o) => {
649				if o == s {
650					Self::SameAsSubject
651				} else if o == p {
652					Self::SameAsPredicate
653				} else {
654					Self::AnyObject
655				}
656			}
657		}
658	}
659
660	pub fn with_any_graph(self) -> quad::canonical::AnySubjectAnyPredicate<T> {
661		match self {
662			Self::AnyObject => quad::canonical::AnySubjectAnyPredicate::AnyObject(
663				quad::canonical::AnySubjectAnyPredicateAnyObject::AnyGraph,
664			),
665			Self::SameAsSubject => quad::canonical::AnySubjectAnyPredicate::SameAsSubject(
666				quad::canonical::AnySubjectAnyPredicateGivenObject::AnyGraph,
667			),
668			Self::SameAsPredicate => quad::canonical::AnySubjectAnyPredicate::SameAsPredicate(
669				quad::canonical::AnySubjectAnyPredicateGivenObject::AnyGraph,
670			),
671			Self::GivenObject(id) => quad::canonical::AnySubjectAnyPredicate::GivenObject(
672				id,
673				quad::canonical::AnySubjectAnyPredicateGivenObject::AnyGraph,
674			),
675		}
676	}
677
678	pub fn object(&self) -> PatternObject<&T> {
679		match self {
680			Self::AnyObject => PatternObject::Any,
681			Self::SameAsSubject => PatternObject::SameAsSubject,
682			Self::SameAsPredicate => PatternObject::SameAsPredicate,
683			Self::GivenObject(id) => PatternObject::Given(id),
684		}
685	}
686
687	pub fn into_object(self) -> PatternObject<T> {
688		match self {
689			Self::AnyObject => PatternObject::Any,
690			Self::SameAsSubject => PatternObject::SameAsSubject,
691			Self::SameAsPredicate => PatternObject::SameAsPredicate,
692			Self::GivenObject(id) => PatternObject::Given(id),
693		}
694	}
695
696	pub fn set_object(&mut self, t: T) -> PatternObject<T> {
697		std::mem::replace(self, Self::GivenObject(t)).into_object()
698	}
699}
700
701#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
702pub enum AnySubjectGivenPredicate<T> {
703	AnyObject,
704	SameAsSubject,
705	GivenObject(T),
706}
707
708impl<T> AnySubjectGivenPredicate<T> {
709	pub fn from_option(o: Option<T>) -> Self {
710		match o {
711			Some(o) => Self::GivenObject(o),
712			None => Self::AnyObject,
713		}
714	}
715
716	pub fn from_pattern<X: PartialEq>(s: X, o: ResourceOrVar<T, X>) -> Self {
717		match o {
718			ResourceOrVar::Resource(o) => Self::GivenObject(o),
719			ResourceOrVar::Var(o) => {
720				if o == s {
721					Self::SameAsSubject
722				} else {
723					Self::AnyObject
724				}
725			}
726		}
727	}
728
729	pub fn with_any_graph(self) -> quad::canonical::AnySubjectGivenPredicate<T> {
730		match self {
731			Self::AnyObject => quad::canonical::AnySubjectGivenPredicate::AnyObject(
732				quad::canonical::AnySubjectGivenPredicateAnyObject::AnyGraph,
733			),
734			Self::SameAsSubject => quad::canonical::AnySubjectGivenPredicate::SameAsSubject(
735				quad::canonical::AnySubjectGivenPredicateGivenObject::AnyGraph,
736			),
737			Self::GivenObject(id) => quad::canonical::AnySubjectGivenPredicate::GivenObject(
738				id,
739				quad::canonical::AnySubjectGivenPredicateGivenObject::AnyGraph,
740			),
741		}
742	}
743
744	pub fn object(&self) -> PatternObject<&T> {
745		match self {
746			Self::AnyObject => PatternObject::Any,
747			Self::SameAsSubject => PatternObject::SameAsSubject,
748			Self::GivenObject(id) => PatternObject::Given(id),
749		}
750	}
751
752	pub fn into_object(self) -> PatternObject<T> {
753		match self {
754			Self::AnyObject => PatternObject::Any,
755			Self::SameAsSubject => PatternObject::SameAsSubject,
756			Self::GivenObject(id) => PatternObject::Given(id),
757		}
758	}
759
760	pub fn set_object(&mut self, t: T) -> PatternObject<T> {
761		std::mem::replace(self, Self::GivenObject(t)).into_object()
762	}
763}
764
765#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
766pub enum GivenSubject<T> {
767	AnyPredicate(GivenSubjectAnyPredicate<T>),
768	GivenPredicate(T, GivenSubjectGivenPredicate<T>),
769}
770
771impl<T> GivenSubject<T> {
772	pub fn from_option_triple(p: Option<T>, o: Option<T>) -> Self {
773		match p {
774			Some(p) => Self::GivenPredicate(p, GivenSubjectGivenPredicate::from_option(o)),
775			None => Self::AnyPredicate(GivenSubjectAnyPredicate::from_option(o)),
776		}
777	}
778
779	pub fn from_pattern<X: PartialEq>(p: ResourceOrVar<T, X>, o: ResourceOrVar<T, X>) -> Self {
780		match p {
781			ResourceOrVar::Resource(p) => {
782				Self::GivenPredicate(p, GivenSubjectGivenPredicate::from_pattern(o))
783			}
784			ResourceOrVar::Var(p) => {
785				Self::AnyPredicate(GivenSubjectAnyPredicate::from_pattern(p, o))
786			}
787		}
788	}
789
790	pub fn with_any_graph(self) -> quad::canonical::GivenSubject<T> {
791		match self {
792			Self::AnyPredicate(o) => {
793				quad::canonical::GivenSubject::AnyPredicate(o.with_any_graph())
794			}
795			Self::GivenPredicate(id, o) => {
796				quad::canonical::GivenSubject::GivenPredicate(id, o.with_any_graph())
797			}
798		}
799	}
800
801	pub fn predicate(&self) -> PatternPredicate<&T> {
802		match self {
803			Self::AnyPredicate(_) => PatternPredicate::Any,
804			Self::GivenPredicate(id, _) => PatternPredicate::Given(id),
805		}
806	}
807
808	pub fn into_predicate(self) -> PatternPredicate<T> {
809		match self {
810			Self::AnyPredicate(_) => PatternPredicate::Any,
811			Self::GivenPredicate(id, _) => PatternPredicate::Given(id),
812		}
813	}
814
815	pub fn object(&self) -> PatternObject<&T> {
816		match self {
817			Self::AnyPredicate(t) => t.object(),
818			Self::GivenPredicate(_, t) => t.object(),
819		}
820	}
821
822	pub fn into_object(self) -> PatternObject<T> {
823		match self {
824			Self::AnyPredicate(t) => t.into_object(),
825			Self::GivenPredicate(_, t) => t.into_object(),
826		}
827	}
828
829	pub fn set_predicate(&mut self, p: T) -> PatternPredicate<T>
830	where
831		T: Clone,
832	{
833		replace_with_or_abort_and_return(self, |this| match this {
834			Self::AnyPredicate(GivenSubjectAnyPredicate::SameAsPredicate) => (
835				PatternPredicate::Any,
836				Self::GivenPredicate(p.clone(), GivenSubjectGivenPredicate::GivenObject(p)),
837			),
838			Self::AnyPredicate(GivenSubjectAnyPredicate::AnyObject) => (
839				PatternPredicate::Any,
840				Self::GivenPredicate(p, GivenSubjectGivenPredicate::AnyObject),
841			),
842			Self::AnyPredicate(GivenSubjectAnyPredicate::GivenObject(o)) => (
843				PatternPredicate::Any,
844				Self::GivenPredicate(p, GivenSubjectGivenPredicate::GivenObject(o)),
845			),
846			Self::GivenPredicate(current_p, o) => (
847				PatternPredicate::Given(current_p),
848				Self::GivenPredicate(p, o),
849			),
850		})
851	}
852
853	pub fn set_object(&mut self, o: T) -> PatternObject<T>
854	where
855		T: Clone,
856	{
857		replace_with_or_abort_and_return(self, |this| match this {
858			Self::AnyPredicate(GivenSubjectAnyPredicate::SameAsPredicate) => (
859				PatternObject::Any,
860				Self::GivenPredicate(o.clone(), GivenSubjectGivenPredicate::GivenObject(o)),
861			),
862			Self::AnyPredicate(mut current_o) => {
863				let old_o = current_o.set_object(o);
864				(old_o, Self::AnyPredicate(current_o))
865			}
866			Self::GivenPredicate(p, mut current_o) => {
867				let old_o = current_o.set_object(o);
868				(old_o, Self::GivenPredicate(p, current_o))
869			}
870		})
871	}
872}
873
874#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
875pub enum GivenSubjectAnyPredicate<T> {
876	AnyObject,
877	SameAsPredicate,
878	GivenObject(T),
879}
880
881impl<T> GivenSubjectAnyPredicate<T> {
882	pub fn from_option(o: Option<T>) -> Self {
883		match o {
884			Some(o) => Self::GivenObject(o),
885			None => Self::AnyObject,
886		}
887	}
888
889	pub fn from_pattern<X: PartialEq>(p: X, o: ResourceOrVar<T, X>) -> Self {
890		match o {
891			ResourceOrVar::Resource(o) => Self::GivenObject(o),
892			ResourceOrVar::Var(o) => {
893				if p == o {
894					Self::SameAsPredicate
895				} else {
896					Self::AnyObject
897				}
898			}
899		}
900	}
901
902	pub fn with_any_graph(self) -> quad::canonical::GivenSubjectAnyPredicate<T> {
903		match self {
904			Self::AnyObject => quad::canonical::GivenSubjectAnyPredicate::AnyObject(
905				quad::canonical::GivenSubjectAnyPredicateAnyObject::AnyGraph,
906			),
907			Self::SameAsPredicate => quad::canonical::GivenSubjectAnyPredicate::SameAsPredicate(
908				quad::canonical::GivenSubjectAnyPredicateGivenObject::AnyGraph,
909			),
910			Self::GivenObject(id) => quad::canonical::GivenSubjectAnyPredicate::GivenObject(
911				id,
912				quad::canonical::GivenSubjectAnyPredicateGivenObject::AnyGraph,
913			),
914		}
915	}
916
917	pub fn as_given(&self) -> Option<&T> {
918		match self {
919			Self::GivenObject(o) => Some(o),
920			_ => None,
921		}
922	}
923
924	pub fn object(&self) -> PatternObject<&T> {
925		match self {
926			Self::AnyObject => PatternObject::Any,
927			Self::SameAsPredicate => PatternObject::SameAsPredicate,
928			Self::GivenObject(id) => PatternObject::Given(id),
929		}
930	}
931
932	pub fn into_object(self) -> PatternObject<T> {
933		match self {
934			Self::AnyObject => PatternObject::Any,
935			Self::SameAsPredicate => PatternObject::SameAsPredicate,
936			Self::GivenObject(id) => PatternObject::Given(id),
937		}
938	}
939
940	pub fn set_object(&mut self, t: T) -> PatternObject<T> {
941		std::mem::replace(self, Self::GivenObject(t)).into_object()
942	}
943}
944
945#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
946pub enum GivenSubjectGivenPredicate<T> {
947	AnyObject,
948	GivenObject(T),
949}
950
951impl<T> GivenSubjectGivenPredicate<T> {
952	pub fn from_option(o: Option<T>) -> Self {
953		match o {
954			Some(o) => Self::GivenObject(o),
955			None => Self::AnyObject,
956		}
957	}
958
959	pub fn from_pattern<X>(o: ResourceOrVar<T, X>) -> Self {
960		match o {
961			ResourceOrVar::Resource(o) => Self::GivenObject(o),
962			ResourceOrVar::Var(_) => Self::AnyObject,
963		}
964	}
965
966	pub fn with_any_graph(self) -> quad::canonical::GivenSubjectGivenPredicate<T> {
967		match self {
968			Self::AnyObject => quad::canonical::GivenSubjectGivenPredicate::AnyObject(
969				quad::canonical::GivenSubjectGivenPredicateAnyObject::AnyGraph,
970			),
971			Self::GivenObject(id) => quad::canonical::GivenSubjectGivenPredicate::GivenObject(
972				id,
973				quad::canonical::GivenSubjectGivenPredicateGivenObject::AnyGraph,
974			),
975		}
976	}
977
978	pub fn as_given(&self) -> Option<&T> {
979		match self {
980			Self::GivenObject(o) => Some(o),
981			_ => None,
982		}
983	}
984
985	pub fn object(&self) -> PatternObject<&T> {
986		match self {
987			Self::AnyObject => PatternObject::Any,
988			Self::GivenObject(id) => PatternObject::Given(id),
989		}
990	}
991
992	pub fn into_object(self) -> PatternObject<T> {
993		match self {
994			Self::AnyObject => PatternObject::Any,
995			Self::GivenObject(id) => PatternObject::Given(id),
996		}
997	}
998
999	pub fn set_object(&mut self, t: T) -> PatternObject<T> {
1000		std::mem::replace(self, Self::GivenObject(t)).into_object()
1001	}
1002}