1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use itertools::Itertools;
use crate::check::context::clss;
use crate::check::context::clss::concrete_to_python;
use crate::check::context::clss::python::{ANY, CALLABLE, TUPLE, UNION};
use crate::check::name::{Empty, Name, Nullable, Union};
use crate::check::name::string_name::StringName;
use crate::check::name::true_name::TrueName;
use crate::generate::ast::node::Core;
use crate::generate::convert::state::Imports;
pub trait ToPy {
fn to_py(&self, imp: &mut Imports) -> Core;
}
impl ToPy for Name {
fn to_py(&self, imp: &mut Imports) -> Core {
if self.names.len() > 1 {
imp.add_from_import("typing", UNION);
let generics: Vec<Name> = self.names.iter().sorted().map(Name::from).collect();
core_type(UNION, &generics, imp)
} else if let Some(name) = self.names.iter().next() {
name.to_py(imp)
} else {
Core::Empty
}
}
}
impl ToPy for TrueName {
fn to_py(&self, imp: &mut Imports) -> Core {
if self.is_nullable() {
imp.add_from_import("typing", "Optional");
core_type("Optional", &[Name::from(&self.variant)], imp)
} else {
self.variant.to_py(imp)
}
}
}
impl ToPy for StringName {
fn to_py(&self, imp: &mut Imports) -> Core {
match self.name.as_str() {
clss::UNION => {
self.generics
.iter()
.sorted()
.fold(Name::empty(), |acc, n| acc.union(n)).to_py(imp)
}
clss::TUPLE => {
imp.add_from_import("typing", TUPLE);
core_type(TUPLE, &self.generics, imp)
}
clss::CALLABLE => {
imp.add_from_import("typing", CALLABLE);
let args = self.generics.get(0).cloned().unwrap_or_else(Name::empty);
let ret = self.generics.get(1).cloned().unwrap_or_else(Name::empty);
core_type(CALLABLE, &[args, ret], imp)
}
other => {
if other == clss::ANY {
imp.add_from_import("typing", ANY);
}
let lit = concrete_to_python(&self.name);
core_type(&lit, &self.generics, imp)
}
}
}
}
fn core_type(lit: &str, generics: &[Name], imp: &mut Imports) -> Core {
Core::Type {
lit: String::from(lit),
generics: generics.iter().map(|core| core.to_py(imp)).collect(),
}
}