Skip to content

Commit

Permalink
tests: add builder tests for name conflicts
Browse files Browse the repository at this point in the history
Test cases of name conflicts between the builder() associated function
generated for the builder API and a getter method generated by the
Message derive for a field named "builder". Provide a doc test on
how to avoid the conflict with the Default impl on the builder struct.
Verify the no-conflict case where the field does not have a getter
generated for it.
  • Loading branch information
mzabaluev committed Mar 9, 2024
1 parent 89b1caf commit dcfed8c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
12 changes: 12 additions & 0 deletions tests/src/builders.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,15 @@ message Zoo {
string b = 5;
}
}

message ConflictProneScalar {
optional int32 builder = 1;
}

message ConflictProneEnum {
AnEnum builder = 1;
}

message ConflictFreeScalar {
string builder = 1;
}
33 changes: 33 additions & 0 deletions tests/src/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,39 @@
/// let message = EmptyForNow::default();
/// ```
///
/// In the (hopefully rare) case when a message has a field named `builder`
/// with the type and labels that cause the `Message` derive generate a getter
/// method for it, the `builder` associated function cannot be generated
/// because it will come into conflict with the getter method:
///
/// ```compile_fail
/// # use tests::builders::builders::ConflictProneScalar;
/// let msg = ConflictProneScalar::builder().build(); // `builder` is a method taking `&self`
/// ```
///
/// ```compile_fail
/// # use tests::builders::builders::ConflictProneEnum;
/// let msg = ConflictProneEnum::builder().build(); // `builder` is a method taking `&self`
/// ```
///
/// The `Default` implementation for the builder type can be used instead:
///
/// ```
/// # use tests::builders::builders::conflict_prone_scalar::ConflictProneScalarBuilder;
/// let msg = ConflictProneScalarBuilder::default().builder(42).build();
/// assert_eq!(msg.builder(), 42);
/// ```
///
/// A plain non-optional scalar field named `builder` should not be problematic,
/// as it has no getter method generated (even though the resulting builder API
/// is confusing):
///
/// ```
/// # use tests::builders::builders::ConflictFreeScalar;
/// let msg = ConflictFreeScalar::builder().builder("hello").build();
/// assert_eq!(msg.builder, "hello");
/// ```
///
pub mod builders {
include!(concat!(env!("OUT_DIR"), "/builders.rs"));
}
Expand Down

0 comments on commit dcfed8c

Please sign in to comment.