starlark/values/
type_repr.rs1use std::marker::PhantomData;
22
23use either::Either;
24pub use starlark_derive::StarlarkTypeRepr;
25
26use crate::typing::Ty;
27use crate::values::list::ListType;
28use crate::values::none::NoneType;
29use crate::values::string::str_type::StarlarkStr;
30use crate::values::Heap;
31use crate::values::StarlarkValue;
32use crate::values::Value;
33
34pub trait StarlarkTypeRepr {
54 type Canonical: StarlarkTypeRepr;
64
65 fn starlark_type_repr() -> Ty;
67}
68
69pub struct SetType<T: StarlarkTypeRepr> {
74 t: PhantomData<T>,
75}
76
77impl<T: StarlarkTypeRepr> StarlarkTypeRepr for SetType<T> {
78 type Canonical = SetType<T::Canonical>;
79
80 fn starlark_type_repr() -> Ty {
81 Ty::set(T::starlark_type_repr())
82 }
83}
84
85impl<'v, T: StarlarkValue<'v>> StarlarkTypeRepr for T {
86 type Canonical = Self;
87
88 fn starlark_type_repr() -> Ty {
89 Self::get_type_starlark_repr()
90 }
91}
92
93impl StarlarkTypeRepr for String {
94 type Canonical = StarlarkStr;
95
96 fn starlark_type_repr() -> Ty {
97 StarlarkStr::starlark_type_repr()
98 }
99}
100
101impl StarlarkTypeRepr for &str {
102 type Canonical = StarlarkStr;
103
104 fn starlark_type_repr() -> Ty {
105 StarlarkStr::starlark_type_repr()
106 }
107}
108
109impl<T: StarlarkTypeRepr> StarlarkTypeRepr for Option<T> {
110 type Canonical = <Either<NoneType, T> as StarlarkTypeRepr>::Canonical;
111
112 fn starlark_type_repr() -> Ty {
113 Either::<NoneType, T>::starlark_type_repr()
114 }
115}
116
117impl<T: StarlarkTypeRepr> StarlarkTypeRepr for Vec<T> {
118 type Canonical = <ListType<T> as StarlarkTypeRepr>::Canonical;
119
120 fn starlark_type_repr() -> Ty {
121 ListType::<T::Canonical>::starlark_type_repr()
122 }
123}
124
125impl<TLeft: StarlarkTypeRepr, TRight: StarlarkTypeRepr> StarlarkTypeRepr for Either<TLeft, TRight> {
126 type Canonical = Either<TLeft::Canonical, TRight::Canonical>;
127
128 fn starlark_type_repr() -> Ty {
129 Ty::union2(TLeft::starlark_type_repr(), TRight::starlark_type_repr())
130 }
131}
132
133#[doc(hidden)]
136pub fn type_repr_from_attr_impl<'v, T: StarlarkTypeRepr, E>(
137 _f: fn(Value<'v>, &'v Heap) -> Result<T, E>,
138) -> Ty {
139 T::starlark_type_repr()
140}
141
142#[cfg(test)]
143mod tests {
144 use crate::tests::util::TestComplexValue;
145 use crate::util::non_static_type_id::non_static_type_id;
146 use crate::values::type_repr::StarlarkTypeRepr;
147 use crate::values::FrozenValue;
148 use crate::values::Value;
149
150 #[test]
151 fn test_canonical_for_complex_value() {
152 assert_ne!(
154 non_static_type_id::<<TestComplexValue<Value> as StarlarkTypeRepr>::Canonical>(),
155 non_static_type_id::<<TestComplexValue<FrozenValue> as StarlarkTypeRepr>::Canonical>(),
156 );
157 }
158}