Commit 2ccaa3e9 authored by Kartikaya Gupta's avatar Kartikaya Gupta Committed by Ryan Hunt

Add a derive_constructor option to generate struct constructors

parent 59104b1e
......@@ -185,6 +185,9 @@ impl FunctionConfig {
pub struct StructConfig {
/// The rename rule to apply to the name of struct fields
pub rename_fields: Option<RenameRule>,
/// Whether to generate a constructor for the struct (which takes
/// arguments to initialize all the members)
pub derive_constructor: bool,
/// Whether to generate a piecewise equality operator
pub derive_eq: bool,
/// Whether to generate a piecewise inequality operator
......@@ -203,6 +206,7 @@ impl Default for StructConfig {
fn default() -> StructConfig {
StructConfig {
rename_fields: None,
derive_constructor: false,
derive_eq: false,
derive_neq: false,
derive_lt: false,
......@@ -214,6 +218,12 @@ impl Default for StructConfig {
}
impl StructConfig {
pub(crate) fn derive_constructor(&self, annotations: &AnnotationSet) -> bool {
if let Some(x) = annotations.bool("derive-constructor") {
return x;
}
self.derive_constructor
}
pub(crate) fn derive_eq(&self, annotations: &AnnotationSet) -> bool {
if let Some(x) = annotations.bool("derive-eq") {
return x;
......
......@@ -232,6 +232,48 @@ impl Source for Struct {
if config.language == Language::Cxx {
let mut wrote_start_newline = false;
if config.structure.derive_constructor(&self.annotations)
&& !self.fields.is_empty()
{
if !wrote_start_newline {
wrote_start_newline = true;
out.new_line();
}
out.new_line();
let arg_renamer = |name: &str| {
config.function.rename_args
.as_ref()
.unwrap_or(&RenameRule::GeckoCase)
.apply_to_snake_case(name, IdentifierType::FunctionArg)
};
write!(out, "{}(", self.name);
out.write_vertical_source_list(
&self.fields
.iter()
.map(|&(ref name, ref ty, _)| {
// const-ref args to constructor
(format!("const& {}", arg_renamer(name)), ty.clone())
})
.collect(),
ListType::Join(","),
);
write!(out, ")");
out.new_line();
write!(out, " : ");
out.write_vertical_source_list(
&self.fields
.iter()
.map(|x| format!("{}({})", x.0, arg_renamer(&x.0)))
.collect(),
ListType::Join(","),
);
out.new_line();
write!(out, "{{}}");
out.new_line();
}
let other = if let Some(r) = config.function.rename_args {
r.apply_to_snake_case("other", IdentifierType::FunctionArg)
} else {
......
......@@ -9,6 +9,10 @@ enum class C : uint32_t {
struct A {
int32_t m0;
A(int32_t const& aM0)
: m0(aM0)
{}
bool operator<(const A& other) const {
return m0 < other.m0;
}
......
/// cbindgen:derive-lt=true
/// cbindgen:derive-lte=true
/// cbindgen:derive-constructor=true
/// cbindgen:rename-all=GeckoCase
#[repr(C)]
struct A(i32);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment