mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-13 09:49:11 +03:00
Bindgen as_Foo and into_Foo for variants
This commit is contained in:
parent
1de7d8abb6
commit
49cf2a8483
@ -190,10 +190,20 @@ fn write_tag_union(
|
||||
if let Some(payload_id) = opt_payload_id {
|
||||
let payload_type = types.get(*payload_id);
|
||||
|
||||
let payload_name = if payload_type.has_pointer(types) {
|
||||
"core::mem::ManuallyDrop::new(payload)"
|
||||
let (init_payload, get_payload, deref_for_as) = if payload_type.has_pointer(types) {
|
||||
(
|
||||
"core::mem::ManuallyDrop::new(payload)",
|
||||
format!(
|
||||
"core::mem::ManuallyDrop::<{}>::into_inner(self.variant.{})",
|
||||
type_name(*payload_id, types),
|
||||
tag_name
|
||||
),
|
||||
// Since this is a ManuallyDrop, our `as_` method will need
|
||||
// to dereference the variant (e.g. `&self.variant.Foo`)
|
||||
"&",
|
||||
)
|
||||
} else {
|
||||
"payload"
|
||||
("payload", format!("self.variant.{}", tag_name), "")
|
||||
};
|
||||
|
||||
let payload_type_name = type_name(*payload_id, types);
|
||||
@ -218,7 +228,37 @@ fn write_tag_union(
|
||||
tag_name,
|
||||
variant_name,
|
||||
tag_name,
|
||||
payload_name
|
||||
init_payload
|
||||
)?;
|
||||
|
||||
writeln!(
|
||||
buf,
|
||||
// Don't use indoc because this must be indented once!
|
||||
r#"
|
||||
/// Unsafely assume the given {} has a .tag() of {} and convert it to {}'s payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_{}(self) -> {} {{
|
||||
{}
|
||||
}}"#,
|
||||
name, tag_name, tag_name, tag_name, payload_type_name, get_payload
|
||||
)?;
|
||||
|
||||
writeln!(
|
||||
buf,
|
||||
// Don't use indoc because this must be indented once!
|
||||
r#"
|
||||
/// Unsafely assume the given {} has a .tag() of {} and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_{}(&self) -> {}{} {{
|
||||
{}self.variant.{}
|
||||
}}"#,
|
||||
name,
|
||||
tag_name,
|
||||
tag_name,
|
||||
deref_for_as,
|
||||
payload_type_name,
|
||||
deref_for_as,
|
||||
tag_name
|
||||
)?;
|
||||
} else {
|
||||
writeln!(
|
||||
@ -239,6 +279,30 @@ fn write_tag_union(
|
||||
}}"#,
|
||||
tag_name, tag_name, discriminant_name, tag_name, variant_name, variant_name,
|
||||
)?;
|
||||
|
||||
writeln!(
|
||||
buf,
|
||||
// Don't use indoc because this must be indented once!
|
||||
r#"
|
||||
/// Other `into_` methods return a payload, but since the {} tag
|
||||
/// has no payload, this does nothing and is only here for completeness.
|
||||
pub fn into_{}(self) -> () {{
|
||||
()
|
||||
}}"#,
|
||||
tag_name, tag_name
|
||||
)?;
|
||||
|
||||
writeln!(
|
||||
buf,
|
||||
// Don't use indoc because this must be indented once!
|
||||
r#"
|
||||
/// Other `as` methods return a payload, but since the {} tag
|
||||
/// has no payload, this does nothing and is only here for completeness.
|
||||
pub unsafe fn as_{}(&self) -> () {{
|
||||
()
|
||||
}}"#,
|
||||
tag_name, tag_name
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,6 +223,18 @@ fn tag_union_aliased() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Bar and convert it to Bar's payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_Bar(self) -> u128 {
|
||||
self.variant.Bar
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Bar and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_Bar(&self) -> u128 {
|
||||
self.variant.Bar
|
||||
}
|
||||
|
||||
/// Construct a tag named Baz
|
||||
pub fn Baz() -> Self {
|
||||
Self {
|
||||
@ -236,6 +248,18 @@ fn tag_union_aliased() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Other `into_` methods return a payload, but since the Baz tag
|
||||
/// has no payload, this does nothing and is only here for completeness.
|
||||
pub fn into_Baz(self) -> () {
|
||||
()
|
||||
}
|
||||
|
||||
/// Other `as` methods return a payload, but since the Baz tag
|
||||
/// has no payload, this does nothing and is only here for completeness.
|
||||
pub unsafe fn as_Baz(&self) -> () {
|
||||
()
|
||||
}
|
||||
|
||||
/// Construct a tag named Blah, with the appropriate payload
|
||||
pub fn Blah(payload: i32) -> Self {
|
||||
Self {
|
||||
@ -246,6 +270,18 @@ fn tag_union_aliased() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Blah and convert it to Blah's payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_Blah(self) -> i32 {
|
||||
self.variant.Blah
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Blah and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_Blah(&self) -> i32 {
|
||||
self.variant.Blah
|
||||
}
|
||||
|
||||
/// Construct a tag named Foo, with the appropriate payload
|
||||
pub fn Foo(payload: roc_std::RocStr) -> Self {
|
||||
Self {
|
||||
@ -255,6 +291,18 @@ fn tag_union_aliased() {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Foo and convert it to Foo's payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_Foo(self) -> roc_std::RocStr {
|
||||
core::mem::ManuallyDrop::<roc_std::RocStr>::into_inner(self.variant.Foo)
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Foo and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_Foo(&self) -> &roc_std::RocStr {
|
||||
&self.variant.Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MyTagUnion {
|
||||
|
Loading…
Reference in New Issue
Block a user