use crate::value::CoercionFamily;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum CoercionId {
Strict,
NumericWiden,
TextCasefold,
CollectionElement,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CoercionSpec {
pub(crate) id: CoercionId,
}
impl CoercionSpec {
#[must_use]
pub const fn new(id: CoercionId) -> Self {
Self { id }
}
#[must_use]
pub const fn id(&self) -> CoercionId {
self.id
}
}
impl Default for CoercionSpec {
fn default() -> Self {
Self::new(CoercionId::Strict)
}
}
#[must_use]
pub(in crate::db) fn supports_coercion(
left: CoercionFamily,
right: CoercionFamily,
id: CoercionId,
) -> bool {
match id {
CoercionId::Strict | CoercionId::CollectionElement => true,
CoercionId::NumericWiden => {
left == CoercionFamily::Numeric && right == CoercionFamily::Numeric
}
CoercionId::TextCasefold => {
left == CoercionFamily::Textual && right == CoercionFamily::Textual
}
}
}
#[cfg(test)]
mod tests {
use crate::{
db::predicate::{CoercionId, coercion::supports_coercion},
value::CoercionFamily,
};
#[test]
fn supports_coercion_matches_canonical_family_matrix() {
assert!(supports_coercion(
CoercionFamily::Numeric,
CoercionFamily::Textual,
CoercionId::Strict,
));
assert!(supports_coercion(
CoercionFamily::Textual,
CoercionFamily::Numeric,
CoercionId::CollectionElement,
));
assert!(supports_coercion(
CoercionFamily::Numeric,
CoercionFamily::Numeric,
CoercionId::NumericWiden,
));
assert!(!supports_coercion(
CoercionFamily::Numeric,
CoercionFamily::Textual,
CoercionId::NumericWiden,
));
assert!(supports_coercion(
CoercionFamily::Textual,
CoercionFamily::Textual,
CoercionId::TextCasefold,
));
assert!(!supports_coercion(
CoercionFamily::Textual,
CoercionFamily::Numeric,
CoercionId::TextCasefold,
));
}
}
crate::retained::retained_copy!(CoercionId);
crate::retained::retained_fields!(CoercionSpec {
Self{id} => [id],
});