icydb_core/db/predicate/
coercion.rs1#[cfg(any(test, feature = "query"))]
7use crate::value::CoercionFamily;
8use std::fmt;
9
10#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20pub enum CoercionId {
21 Strict,
22 NumericWiden,
23 TextCasefold,
24 CollectionElement,
25}
26
27#[derive(Clone, Eq, PartialEq)]
34pub struct CoercionSpec {
35 pub(crate) id: CoercionId,
36 pub(crate) params: Vec<(String, String)>,
37}
38
39impl CoercionSpec {
40 #[must_use]
41 pub const fn new(id: CoercionId) -> Self {
42 Self {
43 id,
44 params: Vec::new(),
45 }
46 }
47
48 #[must_use]
50 pub const fn id(&self) -> CoercionId {
51 self.id
52 }
53
54 #[must_use]
56 pub const fn params(&self) -> &[(String, String)] {
57 self.params.as_slice()
58 }
59}
60
61impl fmt::Debug for CoercionSpec {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 f.debug_struct("CoercionSpec")
64 .field("id", &self.id)
65 .field("params", &CoercionParamsDebug(&self.params))
66 .finish()
67 }
68}
69
70impl Default for CoercionSpec {
71 fn default() -> Self {
72 Self::new(CoercionId::Strict)
73 }
74}
75
76struct CoercionParamsDebug<'a>(&'a [(String, String)]);
79
80impl fmt::Debug for CoercionParamsDebug<'_> {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 let mut debug = f.debug_map();
83 for (key, value) in self.0 {
84 debug.entry(key, value);
85 }
86
87 debug.finish()
88 }
89}
90
91#[must_use]
93#[cfg(any(test, feature = "query"))]
94pub(in crate::db) fn supports_coercion(
95 left: CoercionFamily,
96 right: CoercionFamily,
97 id: CoercionId,
98) -> bool {
99 match id {
100 CoercionId::Strict | CoercionId::CollectionElement => true,
101 CoercionId::NumericWiden => {
102 left == CoercionFamily::Numeric && right == CoercionFamily::Numeric
103 }
104 CoercionId::TextCasefold => {
105 left == CoercionFamily::Textual && right == CoercionFamily::Textual
106 }
107 }
108}
109
110#[cfg(test)]
115mod tests {
116 use crate::{
117 db::predicate::{CoercionId, coercion::supports_coercion},
118 value::CoercionFamily,
119 };
120
121 #[test]
122 fn supports_coercion_matches_canonical_family_matrix() {
123 assert!(supports_coercion(
124 CoercionFamily::Numeric,
125 CoercionFamily::Textual,
126 CoercionId::Strict,
127 ));
128 assert!(supports_coercion(
129 CoercionFamily::Textual,
130 CoercionFamily::Numeric,
131 CoercionId::CollectionElement,
132 ));
133
134 assert!(supports_coercion(
135 CoercionFamily::Numeric,
136 CoercionFamily::Numeric,
137 CoercionId::NumericWiden,
138 ));
139 assert!(!supports_coercion(
140 CoercionFamily::Numeric,
141 CoercionFamily::Textual,
142 CoercionId::NumericWiden,
143 ));
144
145 assert!(supports_coercion(
146 CoercionFamily::Textual,
147 CoercionFamily::Textual,
148 CoercionId::TextCasefold,
149 ));
150 assert!(!supports_coercion(
151 CoercionFamily::Textual,
152 CoercionFamily::Numeric,
153 CoercionId::TextCasefold,
154 ));
155 }
156}