Skip to content

Commit 4003d21

Browse files
Add extensions to the Rust Generated doc page.
PiperOrigin-RevId: 899734732
1 parent a234be8 commit 4003d21

1 file changed

Lines changed: 67 additions & 6 deletions

File tree

content/reference/rust/rust-generated.md

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -662,13 +662,74 @@ enum). Since the generated Rust consts are scoped within the `impl`, the
662662
additional prefix, which is beneficial to add in .proto files, would be
663663
redundant in Rust.
664664

665-
## Extensions (proto2 only) {#extensions}
665+
## Extensions {#extensions}
666666

667-
A Rust API for extensions is currently a work in progress.
668-
Extension fields will be maintained through
669-
parse/serialize, and in a C++ interop case any extensions set will be retained
670-
if the message is accessed from Rust (and propagated in the case of a message
671-
copy or merge).
667+
Protobuf Rust supports extensions for proto2 messages. Extensions are accessed
668+
via generated `ExtensionId` constants.
669+
670+
Given a message with extensions defined:
671+
672+
```proto
673+
package xyz;
674+
message Foo {
675+
extensions 100 to 199;
676+
}
677+
678+
extend Foo {
679+
optional int32 i32_ext = 100;
680+
repeated int32 repeated_i32_ext = 101;
681+
}
682+
```
683+
684+
The compiler generates constants of type `proto::ExtensionId` named `I32_EXT`
685+
and `REPEATED_I32_EXT`, which you can use to read and write the extensions on
686+
the `Foo` type.
687+
688+
### Accessing Extensions {#accessing-exts}
689+
690+
The `ExtensionId` type provides methods to interact with extensions on a
691+
message. These methods work with owned messages, views, and muts.
692+
693+
* `fn has(&self, msg: impl AsView<Target = M>) -> bool`: Returns `true` if the
694+
extension is set on the message. (Not available for repeated extensions, by
695+
design).
696+
* `fn get(&self, msg: impl AsView<Target = M>) -> View<'_, E>`: Returns the
697+
value of the extension. If not set, returns the default value. For repeated
698+
fields, returns a `RepeatedView`.
699+
* `fn set(&self, msg: impl AsMut<Target = M>, value: impl IntoProxied<E>)`:
700+
Sets the value of the extension.
701+
* `fn clear(&self, msg: impl AsMut<Target = M>)`: Clears the extension from
702+
the message.
703+
* `fn get_mut(&self, msg: impl AsMut<Target = M>) -> Mut<'_, E>`: Returns a
704+
mutable handle to the extension. For messages and repeated fields, this will
705+
create the field if it doesn't exist.
706+
707+
### Example Usage {#ext-example}
708+
709+
```rust
710+
use protobuf::prelude::*;
711+
712+
let mut foo = xyz::Foo::new();
713+
714+
// Check and set scalar extension
715+
assert!(!xyz::INT32_EXT.has(&foo));
716+
xyz::INT32_EXT.set(&mut foo, 42);
717+
assert!(xyz::INT32_EXT.has(&foo));
718+
assert_eq!(xyz::INT32_EXT.get(&foo), 42);
719+
720+
// Clear scalar extension
721+
xyz::INT32_EXT.clear(&mut foo);
722+
assert!(!xyz::INT32_EXT.has(&foo));
723+
724+
// Working with repeated extensions
725+
{
726+
let mut rep_mut = xyz::REPEATED_INT32_EXT.get_mut(&mut foo);
727+
rep_mut.push(1);
728+
rep_mut.push(2);
729+
}
730+
assert_eq!(xyz::REPEATED_INT32_EXT.get(&foo).len(), 2);
731+
assert_eq!(xyz::REPEATED_INT32_EXT.get(&foo).get(0), Some(1));
732+
```
672733

673734
## Arena Allocation {#arena}
674735

0 commit comments

Comments
 (0)