mlt_core/convert/
infer.rs1use std::collections::HashMap;
5
6use crate::tile::PropKind;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum InferredKind {
12 Unknown,
13 Bool,
14 I64,
15 U64,
16 F32,
17 F64,
18 Str,
19}
20
21impl InferredKind {
22 #[must_use]
26 pub fn merge(self, other: Self) -> Self {
27 if self == Self::Unknown {
28 return other;
29 }
30 if other == Self::Unknown || self == other {
31 return self;
32 }
33 self.prop_kind().merge(other.prop_kind()).into()
34 }
35
36 #[must_use]
37 pub fn prop_kind(self) -> PropKind {
38 match self {
39 Self::Unknown | Self::Str => PropKind::Str,
40 Self::Bool => PropKind::Bool,
41 Self::I64 => PropKind::I64,
42 Self::U64 => PropKind::U64,
43 Self::F32 => PropKind::F32,
44 Self::F64 => PropKind::F64,
45 }
46 }
47}
48
49impl From<PropKind> for InferredKind {
50 fn from(kind: PropKind) -> Self {
51 match kind {
52 PropKind::Bool => Self::Bool,
53 PropKind::I64 => Self::I64,
54 PropKind::U64 => Self::U64,
55 PropKind::F32 => Self::F32,
56 PropKind::F64 => Self::F64,
57 PropKind::I8 | PropKind::U8 | PropKind::I32 | PropKind::U32 | PropKind::Str => {
58 Self::Str
59 }
60 }
61 }
62}
63
64#[derive(Default)]
66pub(crate) struct ColumnInference<'a> {
67 index: HashMap<&'a str, usize>,
68 names: Vec<String>,
69 kinds: Vec<InferredKind>,
70}
71
72impl<'a> ColumnInference<'a> {
73 pub fn observe(&mut self, name: &'a str, kind: InferredKind) -> usize {
75 let idx = self.column(name);
76 self.merge(idx, kind);
77 idx
78 }
79
80 pub fn column(&mut self, name: &'a str) -> usize {
82 *self.index.entry(name).or_insert_with(|| {
83 self.names.push(name.to_string());
84 self.kinds.push(InferredKind::Unknown);
85 self.names.len() - 1
86 })
87 }
88
89 pub fn merge(&mut self, idx: usize, kind: InferredKind) {
91 let slot = &mut self.kinds[idx];
93 *slot = slot.merge(kind);
94 }
95
96 pub fn finish(self) -> (Vec<String>, Vec<PropKind>) {
98 let kinds = self
99 .kinds
100 .into_iter()
101 .map(InferredKind::prop_kind)
102 .collect();
103 (self.names, kinds)
104 }
105}