Skip to main content

sql_fun_sqlast/sem/schema_file_context/
cast_info.rs

1use std::{collections::HashSet, str::FromStr};
2
3use crate::sem::{BaseParseContext, CastDefinition, CastInfoRead, FullName, TypeReference};
4
5use super::SchemaFileContext;
6
7impl<TBaseContext> CastInfoRead for SchemaFileContext<TBaseContext>
8where
9    TBaseContext: BaseParseContext + std::fmt::Debug,
10{
11    fn get_explicit_cast(
12        &self,
13        source_type: &TypeReference,
14        target_type: &TypeReference,
15    ) -> Option<CastDefinition> {
16        if source_type.is_dynamic() || target_type.is_dynamic() {
17            return None;
18        }
19
20        if let Some(s) = self.casts.get(&source_type.to_string())
21            && let Some(t) = s.get(&target_type.to_string())
22        {
23            if t.use_in_explicit() {
24                Some(t.clone())
25            } else {
26                None
27            }
28        } else {
29            self.base.get_explicit_cast(source_type, target_type)
30        }
31    }
32
33    fn get_implicit_castable(&self, source_type: &TypeReference) -> HashSet<TypeReference> {
34        let mut castable = self.base.get_implicit_castable(source_type);
35
36        if let Some(s) = self.casts.get(&source_type.to_string()) {
37            for (k, v) in s.iter() {
38                if v.use_in_implicit() {
39                    castable.insert(TypeReference::from_full_name(
40                        FullName::from_str(k.as_str()).expect("key parseable"),
41                    ));
42                }
43            }
44        }
45
46        // source_type -> source_type is always avaiable with no conversion
47        if !castable.contains(source_type) {
48            castable.insert(source_type.clone());
49        }
50
51        castable
52    }
53
54    fn get_implicit_cast(
55        &self,
56        source_type: &TypeReference,
57        target_type: &TypeReference,
58    ) -> Option<CastDefinition> {
59        if source_type.is_dynamic() || target_type.is_dynamic() {
60            return None;
61        }
62
63        if let Some(s) = self.casts.get(&source_type.to_string())
64            && let Some(t) = s.get(&target_type.to_string())
65        {
66            if t.use_in_implicit() {
67                Some(t.clone())
68            } else {
69                None
70            }
71        } else {
72            self.base.get_explicit_cast(source_type, target_type)
73        }
74    }
75}