Skip to content
Merged
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
19 changes: 11 additions & 8 deletions examples/async_more/src/org_example_more.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,25 @@ pub trait VarlinkCallError: varlink::CallTrait {
}
}
impl VarlinkCallError for varlink::Call<'_> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct r#State {
#[serde(skip_serializing_if = "Option::is_none")]
pub r#start: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#progress: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#end: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct TestMoreError_Args {
pub r#reason: String,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Reply {
pub r#pong: String,
}
impl varlink::VarlinkReply for Ping_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Args {
pub r#ping: String,
}
Expand All @@ -159,23 +162,23 @@ pub trait Call_Ping: VarlinkCallError + Send {
self.reply_struct(Ping_Reply { r#pong }.into())
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct StopServing_Reply {}
impl varlink::VarlinkReply for StopServing_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct StopServing_Args {}
#[allow(dead_code)]
pub trait Call_StopServing: VarlinkCallError + Send {
fn reply(&mut self) -> varlink::Result<()> {
self.reply_struct(varlink::Reply::parameters(None))
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct TestMore_Reply {
pub r#state: State,
}
impl varlink::VarlinkReply for TestMore_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct TestMore_Args {
pub r#n: i64,
}
Expand Down
6 changes: 3 additions & 3 deletions examples/async_ping/src/org_example_ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,16 @@ pub trait VarlinkCallError: varlink::CallTrait {
}
}
impl VarlinkCallError for varlink::Call<'_> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct PingError_Args {
pub r#parameter: i64,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Reply {
pub r#pong: String,
}
impl varlink::VarlinkReply for Ping_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Args {
pub r#ping: String,
}
Expand Down
19 changes: 11 additions & 8 deletions examples/more/src/org_example_more.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,22 +133,25 @@ pub trait VarlinkCallError: varlink::CallTrait {
}
}
impl VarlinkCallError for varlink::Call<'_> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct r#State {
#[serde(skip_serializing_if = "Option::is_none")]
pub r#start: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#progress: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#end: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct TestMoreError_Args {
pub r#reason: String,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Reply {
pub r#pong: String,
}
impl varlink::VarlinkReply for Ping_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Args {
pub r#ping: String,
}
Expand All @@ -159,10 +162,10 @@ pub trait Call_Ping: VarlinkCallError {
}
}
impl Call_Ping for varlink::Call<'_> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct StopServing_Reply {}
impl varlink::VarlinkReply for StopServing_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct StopServing_Args {}
#[allow(dead_code)]
pub trait Call_StopServing: VarlinkCallError {
Expand All @@ -171,12 +174,12 @@ pub trait Call_StopServing: VarlinkCallError {
}
}
impl Call_StopServing for varlink::Call<'_> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct TestMore_Reply {
pub r#state: State,
}
impl varlink::VarlinkReply for TestMore_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct TestMore_Args {
pub r#n: i64,
}
Expand Down
10 changes: 5 additions & 5 deletions examples/ping/src/org_example_ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,16 @@ pub trait VarlinkCallError: varlink::CallTrait {
}
}
impl VarlinkCallError for varlink::Call<'_> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct PingError_Args {
pub r#parameter: i64,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Reply {
pub r#pong: String,
}
impl varlink::VarlinkReply for Ping_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Ping_Args {
pub r#ping: String,
}
Expand All @@ -151,10 +151,10 @@ pub trait Call_Ping: VarlinkCallError {
}
}
impl Call_Ping for varlink::Call<'_> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Upgrade_Reply {}
impl varlink::VarlinkReply for Upgrade_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct Upgrade_Args {}
#[allow(dead_code)]
pub trait Call_Upgrade: VarlinkCallError {
Expand Down
10 changes: 7 additions & 3 deletions varlink_generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,12 @@ fn generate_error_code(
) {
// Errors traits
{
let mut error_structs_and_enums = TokenStream::new();
// Scratch sink for the anonymous helper types produced as a side effect
// of `to_rust_string` below. We only need the type *names* here (for the
// reply_* signatures); the definitions themselves are emitted by
// `VError::to_tokenstream` alongside each error's `_Args` struct. Emitting
// them here too would duplicate every anonymous error helper type.
let mut discard = TokenStream::new();
let mut funcs = TokenStream::new();
{
let mut errors = Vec::new();
Expand Down Expand Up @@ -1093,7 +1098,7 @@ fn generate_error_code(
e.vtype
.to_rust_string(
format!("{}_Args_{}", t.name, e.name).as_ref(),
&mut error_structs_and_enums,
&mut discard,
options,
)
.as_ref(),
Expand Down Expand Up @@ -1122,7 +1127,6 @@ fn generate_error_code(
));
}
ts.extend(quote!(
#error_structs_and_enums
#[allow(dead_code)]
pub trait VarlinkCallError: varlink::CallTrait {
#funcs
Expand Down
19 changes: 19 additions & 0 deletions varlink_generator/tests/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,22 @@ fn test_generate() {
let _ = std::fs::remove_file(path);
let _ = std::fs::remove_file(path2);
}

// Regression: an `error` whose parameters contain anonymous nested types must
// emit each generated helper type exactly once. The error definitions are
// visited by two passes (the error-code/reply_* generation and the per-error
// `_Args` struct generation); a bug had both passes emit the anonymous helper
// types, producing duplicate `struct`/`enum` definitions that fail to compile.
#[test]
fn error_anonymous_types_emitted_once() {
let src = "interface org.example.test\n\
error Foo (bar: (a: int, b: string), baz: (x: bool))\n";
let code = varlink_generator::compile(src.to_string())
.unwrap()
.to_string();

for def in ["struct r#Foo_Args_bar", "struct r#Foo_Args_baz"] {
let count = code.matches(def).count();
assert_eq!(count, 1, "`{def}` was emitted {count} times, expected once");
}
}
17 changes: 0 additions & 17 deletions varlink_generator/tests/org.example.complex.rs_out
Original file line number Diff line number Diff line change
Expand Up @@ -129,23 +129,6 @@ impl From<&varlink::Reply> for ErrorKind {
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub struct r#ErrorFoo_Args_enum {
pub r#b: bool,
pub r#c: i64,
pub r#interface: Interface,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
pub enum r#ErrorFoo_Args_bar {
#[default]
r#type,
r#enum,
r#int,
r#bool,
r#string,
r#if,
r#let,
}
#[allow(dead_code)]
pub trait VarlinkCallError: varlink::CallTrait {
fn reply_error_bar(&mut self) -> varlink::Result<()> {
Expand Down
Loading