partiql_value/
bindings.rs1use crate::datum::OwnedFieldView;
2use crate::{PairsIntoIter, PairsIter, Value};
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use std::borrow::Cow;
6use std::iter::Once;
7use unicase::UniCase;
8
9#[derive(Clone, Hash, Debug, Eq, PartialEq)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11#[non_exhaustive]
12pub enum BindingsName<'s> {
13 CaseSensitive(Cow<'s, str>),
14 CaseInsensitive(Cow<'s, str>),
15}
16
17impl<'s> BindingsName<'s> {
18 pub fn matcher(&'s self) -> BindingsMatcher<'s> {
19 BindingsMatcher::from(self)
20 }
21}
22
23#[derive(Clone, Hash, Debug, Eq, PartialEq)]
24#[non_exhaustive]
25pub enum BindingsMatcher<'s> {
26 CaseSensitive(&'s str),
27 CaseInsensitive(UniCase<&'s str>),
28}
29
30impl<'s> BindingsMatcher<'s> {
31 pub fn matches(&'s self, candidate: &str) -> bool {
32 match self {
33 BindingsMatcher::CaseSensitive(target) => *target == candidate,
34 BindingsMatcher::CaseInsensitive(target) => *target == UniCase::new(candidate),
35 }
36 }
37}
38
39impl<'s> From<&'s BindingsName<'s>> for BindingsMatcher<'s> {
40 fn from(name: &'s BindingsName<'_>) -> Self {
41 match name {
42 BindingsName::CaseSensitive(s) => BindingsMatcher::CaseSensitive(s.as_ref()),
43 BindingsName::CaseInsensitive(s) => {
44 BindingsMatcher::CaseInsensitive(UniCase::new(s.as_ref()))
45 }
46 }
47 }
48}
49
50#[non_exhaustive]
51pub enum BindingIter<'a> {
52 Tuple(PairsIter<'a>),
53 Dynamic(Box<dyn Iterator<Item = (Option<&'a str>, &'a Value)> + 'a>),
54 Single(Once<&'a Value>),
55 Empty,
56}
57
58impl<'a> Iterator for BindingIter<'a> {
59 type Item = (Option<&'a str>, &'a Value);
60
61 #[inline]
62 fn next(&mut self) -> Option<Self::Item> {
63 match self {
64 BindingIter::Tuple(t) => t.next().map(|(k, v)| (Some(k.as_str()), v)),
65 BindingIter::Single(single) => single.next().map(|v| (None, v)),
66 BindingIter::Empty => None,
67 BindingIter::Dynamic(d) => d.next(),
68 }
69 }
70
71 #[inline]
72 fn size_hint(&self) -> (usize, Option<usize>) {
73 match self {
74 BindingIter::Tuple(t) => t.size_hint(),
75 BindingIter::Single(_single) => (1, Some(1)),
76 BindingIter::Empty => (0, Some(0)),
77 BindingIter::Dynamic(d) => d.size_hint(),
78 }
79 }
80}
81
82#[non_exhaustive]
83pub enum BindingIntoIter {
84 Tuple(PairsIntoIter),
85 Single(Once<Value>),
86 Empty,
87 DynTuple(Box<dyn Iterator<Item = OwnedFieldView<Value>>>),
88}
89
90impl Iterator for BindingIntoIter {
91 type Item = (Option<String>, Value);
92
93 #[inline]
94 fn next(&mut self) -> Option<Self::Item> {
95 match self {
96 BindingIntoIter::Tuple(t) => t.next().map(|(k, v)| (Some(k), v)),
97 BindingIntoIter::Single(single) => single.next().map(|v| (None, v)),
98 BindingIntoIter::Empty => None,
99 BindingIntoIter::DynTuple(d) => d.next().map(|f| (Some(f.name), f.value)),
100 }
101 }
102
103 #[inline]
104 fn size_hint(&self) -> (usize, Option<usize>) {
105 match self {
106 BindingIntoIter::Tuple(t) => t.size_hint(),
107 BindingIntoIter::Single(_single) => (1, Some(1)),
108 BindingIntoIter::Empty => (0, Some(0)),
109 BindingIntoIter::DynTuple(d) => d.size_hint(),
110 }
111 }
112}