in antlir/bzl/shape2/bzl2ir.rs [166:292]
fn shape(builder: &mut GlobalsBuilder) {
fn shape(kwargs: DictOf<'v, &str, Value<'v>>) -> anyhow::Result<TypeId> {
let mut reg = get_type_registry(eval)?.try_borrow_mut()?;
let fields = kwargs
.to_dict()
.into_iter()
.filter(|(key, _)| *key != "__I_AM_TARGET__")
.map(|(key, val)| val.try_to_field(®).map(|f| (key.into(), f)))
.collect::<Result<_>>()?;
let s = ir::Struct {
fields,
docstring: None,
name: None,
};
let ty = ir::Type::Complex(ir::ComplexType::Struct(s));
Ok(reg.add(ty))
}
fn list(ty: Value<'v>) -> anyhow::Result<StarlarkType> {
let reg = get_type_registry(eval)?.try_borrow()?;
ty.try_to_type(®)
.map(|ty| ir::Type::List { item_type: ty })
.map(Rc::new)
.map(StarlarkType)
}
fn r#enum(args: Value<'v>) -> anyhow::Result<TypeId> {
let mut reg = get_type_registry(eval)?.try_borrow_mut()?;
let options = args
.iterate_collect(heap)
.context("while collecting enum variants")?
.into_iter()
.map(|v| String::unpack_param(v).map(|s| s.into()))
.collect::<Result<_>>()?;
let enm = ir::Enum {
options,
docstring: None,
name: None,
};
let ty = ir::Type::Complex(ir::ComplexType::Enum(enm));
Ok(reg.add(ty))
}
fn field(
ty: Value<'v>,
optional @ false: bool,
default: Option<Value<'v>>,
) -> anyhow::Result<StarlarkField> {
let reg = get_type_registry(eval)?.try_borrow()?;
ty.try_to_type(®)
.and_then(|ty| {
Ok(ir::Field {
ty,
required: !optional,
default_value: default
.map(|d| {
d.to_json().and_then(|s| {
serde_json::from_str(&s).context("parsing result of to_json")
})
})
.transpose()?,
})
})
.map(StarlarkField)
}
fn new(
_shape: Value<'v>,
kwargs: DictOf<'v, StringValue<'v>, Value<'v>>,
) -> anyhow::Result<StructGen<'v, Value<'v>>> {
// no need to type-check, since it will already be done at buck parse
// time, and will also be done when loading the json
Ok(StructGen::new(kwargs.to_dict()))
}
fn dict(key_type: Value<'v>, value_type: Value<'v>) -> anyhow::Result<StarlarkType> {
let reg = get_type_registry(eval)?.try_borrow()?;
let key_type = key_type
.try_to_type(®)
.context("dict key must be a type")?;
let value_type = value_type
.try_to_type(®)
.context("dict value must be a type")?;
Ok(StarlarkType(Rc::new(ir::Type::Map {
key_type,
value_type,
})))
}
fn tuple(args: Value<'v>) -> anyhow::Result<StarlarkType> {
let reg = get_type_registry(eval)?.try_borrow()?;
let item_types = args
.iterate_collect(heap)?
.into_iter()
.enumerate()
.map(|(i, v)| {
v.try_to_type(®)
.with_context(|| format!("tuple item at {} is not a type", i))
})
.collect::<Result<_>>()?;
Ok(StarlarkType(Rc::new(ir::Type::Tuple { item_types })))
}
fn union(args: Value<'v>) -> anyhow::Result<TypeId> {
let mut reg = get_type_registry(eval)?.try_borrow_mut()?;
let types = args
.iterate_collect(heap)?
.into_iter()
.enumerate()
.map(|(i, v)| {
v.try_to_type(®)
.with_context(|| format!("union item at {} is not a type", i))
})
.collect::<Result<_>>()?;
let u = ir::Union {
types,
docstring: None,
name: None,
};
let ty = ir::Type::Complex(ir::ComplexType::Union(u));
Ok(reg.add(ty))
}
fn path() -> anyhow::Result<StarlarkField> {
Err(anyhow!("shape.path is no longer a callable function"))
}
}