Add SettableValue for generic field setting

This is a prerequisite for optional types to have proper setters.

PiperOrigin-RevId: 542588427
diff --git a/rust/internal.rs b/rust/internal.rs
index ae07849..a96437d 100644
--- a/rust/internal.rs
+++ b/rust/internal.rs
@@ -34,6 +34,9 @@
 
 use std::slice;
 
+/// Used to protect internal-only items from being used accidentally.
+pub struct Private;
+
 /// Represents an ABI-stable version of `NonNull<[u8]>`/`string_view` (a
 /// borrowed slice of bytes) for FFI use only.
 ///
diff --git a/rust/optional.rs b/rust/optional.rs
index b5b4169..5adab27 100644
--- a/rust/optional.rs
+++ b/rust/optional.rs
@@ -32,7 +32,8 @@
 #![allow(dead_code)]
 #![allow(unused)]
 
-use crate::{Mut, MutProxy, Proxied, View, ViewProxy};
+use crate::__internal::Private;
+use crate::{Mut, MutProxy, Proxied, SettableValue, View, ViewProxy};
 use std::convert::{AsMut, AsRef};
 use std::fmt::{self, Debug};
 
@@ -118,8 +119,11 @@
     /// Sets the value of this field to `val`.
     ///
     /// Equivalent to `self.or_default().set(val)`.
-    pub fn set(&mut self, val: Todo) {
-        todo!("b/285308646: Requires a trait method")
+    pub fn set(&mut self, val: impl SettableValue<T>) {
+        match self {
+            Optional::Set(x) => x.set(val),
+            Optional::Unset(x) => todo!(),
+        }
     }
 
     /// Clears the field; `is_set()` will return `false`.
@@ -181,8 +185,8 @@
         self.into_view()
     }
 
-    pub fn set(&mut self, val: Todo) {
-        todo!("b/285308646: Requires a trait method")
+    pub fn set(&mut self, val: impl SettableValue<T>) {
+        val.set_on(Private, self.as_mut())
     }
 
     /// See [`FieldEntry::clear`].
@@ -253,7 +257,7 @@
 
     /// See [`FieldEntry::set`]. Note that this consumes and returns a
     /// `PresentField`.
-    pub fn set(self, val: Todo) -> PresentField<'msg, T> {
+    pub fn set(self, val: impl SettableValue<T>) -> PresentField<'msg, T> {
         todo!("b/285308646: Requires a trait method")
     }
 
diff --git a/rust/proxied.rs b/rust/proxied.rs
index dd4d30f..e8c16df 100644
--- a/rust/proxied.rs
+++ b/rust/proxied.rs
@@ -67,6 +67,7 @@
 //! implemented the concept of "proxy" types. Proxy types are a reference-like
 //! indirection between the user and the internal memory representation.
 
+use crate::__internal::Private;
 use std::fmt::Debug;
 use std::marker::{Send, Sync};
 
@@ -169,6 +170,13 @@
 /// This trait is intentionally made non-object-safe to prevent a potential
 /// future incompatible change.
 pub trait MutProxy<'a>: ViewProxy<'a> {
+    /// Sets this field to the given `val`.
+    ///
+    /// Any borrowed data from `val` will be cloned.
+    fn set(&mut self, val: impl SettableValue<Self::Proxied>) {
+        val.set_on(Private, self.as_mut())
+    }
+
     /// Converts a borrow into a `Mut` with the lifetime of that borrow.
     ///
     /// This function enables calling multiple methods consuming `self`, for
@@ -211,11 +219,22 @@
         'a: 'shorter;
 }
 
+/// Values that can be used to set a field of `T`.
+pub trait SettableValue<T>
+where
+    T: Proxied + ?Sized,
+{
+    /// Consumes `self` to set the given mutator to its value.
+    #[doc(hidden)]
+    fn set_on(self, _private: Private, mutator: Mut<T>);
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
+    use std::borrow::Cow;
 
-    #[derive(Debug, PartialEq)]
+    #[derive(Debug, Default, PartialEq)]
     struct MyProxied {
         val: String,
     }
@@ -266,12 +285,6 @@
         my_proxied_ref: &'a mut MyProxied,
     }
 
-    impl MyProxiedMut<'_> {
-        fn set_val(&mut self, new_val: String) {
-            self.my_proxied_ref.val = new_val;
-        }
-    }
-
     impl<'a> ViewProxy<'a> for MyProxiedMut<'a> {
         type Proxied = MyProxied;
 
@@ -299,6 +312,27 @@
         }
     }
 
+    impl SettableValue<MyProxied> for String {
+        fn set_on(self, _private: Private, mutator: Mut<MyProxied>) {
+            mutator.my_proxied_ref.val = self;
+        }
+    }
+
+    impl SettableValue<MyProxied> for &'_ str {
+        fn set_on(self, _private: Private, mutator: Mut<MyProxied>) {
+            mutator.my_proxied_ref.val.replace_range(.., self);
+        }
+    }
+
+    impl SettableValue<MyProxied> for Cow<'_, str> {
+        fn set_on(self, _private: Private, mutator: Mut<MyProxied>) {
+            match self {
+                Cow::Owned(x) => x.set_on(Private, mutator),
+                Cow::Borrowed(x) => x.set_on(Private, mutator),
+            }
+        }
+    }
+
     #[test]
     fn test_as_view() {
         let my_proxied = MyProxied { val: "Hello World".to_string() };
@@ -313,7 +347,7 @@
         let mut my_proxied = MyProxied { val: "Hello World".to_string() };
 
         let mut my_mut = my_proxied.as_mut();
-        my_mut.set_val("Hello indeed".to_string());
+        my_mut.set("Hello indeed".to_string());
 
         let val_after_set = my_mut.as_view().val().to_string();
         assert_eq!(my_proxied.val, val_after_set);
@@ -443,4 +477,17 @@
             reborrow_generic_mut_into_mut::<MyProxied>(my_mut, other_mut);
         }
     }
+
+    #[test]
+    fn test_set() {
+        let mut my_proxied = MyProxied::default();
+        my_proxied.as_mut().set("hello");
+        assert_eq!(my_proxied.as_view().val(), "hello");
+
+        my_proxied.as_mut().set(String::from("hello2"));
+        assert_eq!(my_proxied.as_view().val(), "hello2");
+
+        my_proxied.as_mut().set(Cow::Borrowed("hello3"));
+        assert_eq!(my_proxied.as_view().val(), "hello3");
+    }
 }
diff --git a/rust/shared.rs b/rust/shared.rs
index aab8693..b27f363 100644
--- a/rust/shared.rs
+++ b/rust/shared.rs
@@ -47,7 +47,7 @@
 mod proxied;
 
 pub use optional::{AbsentField, FieldEntry, Optional, PresentField};
-pub use proxied::{Mut, MutProxy, Proxied, View, ViewProxy};
+pub use proxied::{Mut, MutProxy, Proxied, SettableValue, View, ViewProxy};
 
 /// Everything in `__internal` is allowed to change without it being considered
 /// a breaking change for the protobuf library. Nothing in here should be