Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ Options:
Generate exhaustively matchable enums and unions [default: false] [possible values: true, false]
--serializeEmptyCollections[=<SERIALIZE_EMPTY_COLLECTIONS>]
Include empty collection fields in serialized output [default: false] [possible values: true, false]
--useLegacyErrorSerialization[=<USE_LEGACY_ERROR_SERIALIZATION>]
Serialize service error parameters in their legacy stringified form [default: true] [possible values: true, false]
--publicFields[=<PUBLIC_FIELDS>]
Make struct fields public [default: false] [possible values: true, false]
--stripPrefix <prefix>
Strip a prefix from types's package paths
--productName <name>
Expand All @@ -39,14 +43,14 @@ Options:
--extraManifestJson <json>
Extra manifest configuration as a JSON object.
This JSON will be converted to TOML and merged into the generated Cargo.toml manifest.

Example:
--extraManifestJson '{
"package": { "publish": ["some-registry-name"], "license": "MIT" },
"dependencies": { "serde": { "version": "1.0", "features": ["default"] } },
"features": { "fancy-feature": ["foo", "bar"] }
}'

Use single quotes to avoid shell escaping issues.
-h, --help
Print help
Expand Down
7 changes: 7 additions & 0 deletions conjure-codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub struct Context {
exhaustive: bool,
serialize_empty_collections: bool,
use_legacy_error_serialization: bool,
public_fields: bool,
strip_prefix: Vec<String>,
version: Option<String>,
}
Expand All @@ -71,6 +72,7 @@ impl Context {
exhaustive: bool,
serialize_empty_collections: bool,
use_legacy_error_serialization: bool,
public_fields: bool,
strip_prefix: Option<&str>,
version: Option<&str>,
) -> Context {
Expand All @@ -79,6 +81,7 @@ impl Context {
exhaustive,
serialize_empty_collections,
use_legacy_error_serialization,
public_fields,
strip_prefix: vec![],
version: version.map(str::to_owned),
};
Expand Down Expand Up @@ -133,6 +136,10 @@ impl Context {
self.use_legacy_error_serialization
}

pub fn public_fields(&self) -> bool {
self.public_fields
}

fn needs_box(&self, def: &Type) -> bool {
match def {
Type::Primitive(_) => false,
Expand Down
17 changes: 17 additions & 0 deletions conjure-codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
//! assert_eq!(object.coin(), true);
//! ```
//!
//! By default, struct fields are private and have accessor methods. The [`Config::public_fields`] option can be set to
//! make the fields public.
//!
//! The generated structs implement `Debug`, `Clone`, `PartialEq`, Eq, `PartialOrd`, `Ord`, `Hash`, `Serialize`, and
//! `Deserialize`. They implement `Copy` if they consist entirely of copyable primitive types.
//!
Expand Down Expand Up @@ -329,6 +332,7 @@ pub struct Config {
exhaustive: bool,
serialize_empty_collections: bool,
use_legacy_error_serialization: bool,
public_fields: bool,
strip_prefix: Option<String>,
version: Option<String>,
build_crate: Option<CrateInfo>,
Expand All @@ -348,6 +352,7 @@ impl Config {
exhaustive: false,
serialize_empty_collections: false,
use_legacy_error_serialization: true,
public_fields: false,
strip_prefix: None,
version: None,
build_crate: None,
Expand Down Expand Up @@ -395,6 +400,17 @@ impl Config {
self
}

/// Controls visibility of fields in objects.
///
/// If enabled, fields will be public, but the struct will be annotated `#[non_exhaustive]`. If disabled, fields
/// will be private and accessor methods will be defined.
///
/// Defaults to `false`.
pub fn public_fields(&mut self, public_fields: bool) -> &mut Config {
self.public_fields = public_fields;
self
}

/// Sets a prefix that will be stripped from package names.
///
/// Defaults to `None`.
Expand Down Expand Up @@ -488,6 +504,7 @@ impl Config {
self.exhaustive,
self.serialize_empty_collections,
self.use_legacy_error_serialization,
self.public_fields,
self.strip_prefix.as_deref(),
self.version
.as_deref()
Expand Down
26 changes: 25 additions & 1 deletion conjure-codegen/src/objects.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::iter;

// Copyright 2021 Palantir Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -47,6 +49,10 @@ pub fn generate(ctx: &Context, base_module: BaseModule, def: &ObjectDefinition)
// The derive attr has to be before the educe attr, so insert rather than push
type_attrs.insert(0, quote!(#[derive(#(#derives),*)]));

if ctx.public_fields() {
type_attrs.push(quote!(#[non_exhaustive]));
}

let field_attrs = def.fields().iter().map(|s| {
let builder_attr = field_builder_attr(ctx, base_module, def, s);
let serde_attr = serde_field_attr(ctx, def, s);
Expand All @@ -61,13 +67,27 @@ pub fn generate(ctx: &Context, base_module: BaseModule, def: &ObjectDefinition)
} else {
quote!()
};
let (docs, deprecated) = if ctx.public_fields() {
(ctx.docs(s.docs()), ctx.deprecated(s.docs()))
} else {
(quote!(), quote!())
};

quote! {
#builder_attr
#serde_attr
#educe_attr
#docs
#deprecated
}
});

let pub_ = if ctx.public_fields() {
quote!(pub)
} else {
quote!()
};
let pub_ = iter::repeat(pub_);
let fields = def.fields().iter().map(|f| ctx.field_name(f.field_name()));
let boxed_types = &def
.fields()
Expand All @@ -78,6 +98,10 @@ pub fn generate(ctx: &Context, base_module: BaseModule, def: &ObjectDefinition)
let constructor = generate_constructor(ctx, base_module, def);

let accessors = def.fields().iter().map(|s| {
if ctx.public_fields() {
return quote!();
}

let docs = ctx.docs(s.docs());
let deprecated = ctx.deprecated(s.deprecated());
let name = ctx.field_name(s.field_name());
Expand Down Expand Up @@ -106,7 +130,7 @@ pub fn generate(ctx: &Context, base_module: BaseModule, def: &ObjectDefinition)
pub struct #name {
#(
#field_attrs
#fields: #boxed_types,
#pub_ #fields: #boxed_types,
)*
}

Expand Down
13 changes: 12 additions & 1 deletion conjure-rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ struct Args {
action = ArgAction::Set,
)]
use_legacy_error_serialization: bool,
/// Make struct fields public
#[clap(
long,
default_missing_value = "true",
default_value = "false",
num_args = 0..=1,
require_equals = true,
action = ArgAction::Set,
)]
public_fields: bool,
/// Strip a prefix from types's package paths
#[clap(long, value_name = "prefix")]
strip_prefix: Option<String>,
Expand Down Expand Up @@ -107,7 +117,8 @@ fn main() {
config
.exhaustive(args.exhaustive)
.serialize_empty_collections(args.serialize_empty_collections)
.use_legacy_error_serialization(args.use_legacy_error_serialization);
.use_legacy_error_serialization(args.use_legacy_error_serialization)
.public_fields(args.public_fields);
if let Some(prefix) = args.strip_prefix {
config.strip_prefix(prefix);
}
Expand Down
1 change: 1 addition & 0 deletions conjure-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fn main() {
conjure_codegen::Config::new()
.strip_prefix("com.palantir.conjure".to_string())
.exhaustive(true)
.public_fields(true)
.generate_files(input, output)
.unwrap();
}