@@ -662,13 +662,74 @@ enum). Since the generated Rust consts are scoped within the `impl`, the
662662additional prefix, which is beneficial to add in .proto files, would be
663663redundant 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