Allow non-repeated StringPiece accessors to be generated.

Add tests for this case as well as repeated and non-repeated Editions string_view typed fields.

PiperOrigin-RevId: 642264883
diff --git a/rust/test/BUILD b/rust/test/BUILD
index aa673aa..0fedc17 100644
--- a/rust/test/BUILD
+++ b/rust/test/BUILD
@@ -136,6 +136,7 @@
     name = "edition2023_proto",
     testonly = True,
     srcs = ["edition2023.proto"],
+    deps = ["//src/google/protobuf:cpp_features_proto"],
 )
 
 rust_cc_proto_library(
diff --git a/rust/test/edition2023.proto b/rust/test/edition2023.proto
index d5c48a2..3d5450c 100644
--- a/rust/test/edition2023.proto
+++ b/rust/test/edition2023.proto
@@ -2,7 +2,13 @@
 
 package test;
 
+import "google/protobuf/cpp_features.proto";
+
 message EditionsMessage {
   int32 plain_field = 1;
   int32 implicit_presence_field = 2 [features.field_presence = IMPLICIT];
+
+  string str_view = 3 [features.(pb.cpp).string_type = VIEW];
+  repeated string repeated_str_view = 4 [features.(pb.cpp).string_type = VIEW];
+  repeated string repeated_str = 5;
 }
diff --git a/rust/test/shared/accessors_proto3_test.rs b/rust/test/shared/accessors_proto3_test.rs
index f7517e3..f4096ea 100644
--- a/rust/test/shared/accessors_proto3_test.rs
+++ b/rust/test/shared/accessors_proto3_test.rs
@@ -243,3 +243,11 @@
 
     assert_that!(parent.optional_nested_message().bb(), eq(7));
 }
+
+#[test]
+fn test_ctype_stringpiece() {
+    let mut msg = TestAllTypes::new();
+    assert_that!(msg.optional_string_piece(), eq(""));
+    msg.set_optional_string_piece("hello");
+    assert_that!(msg.optional_string_piece(), eq("hello"));
+}
diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs
index 262d0c8..956ff06 100644
--- a/rust/test/shared/accessors_test.rs
+++ b/rust/test/shared/accessors_test.rs
@@ -814,3 +814,13 @@
     assert_that!(submsg_clone.bb(), eq(7));
     assert_that!(submsg_mut.bb(), eq(8));
 }
+
+#[test]
+fn test_ctype_stringpiece() {
+    let mut msg = TestAllTypes::new();
+    assert_that!(msg.optional_string_piece(), eq(""));
+    assert_that!(msg.has_optional_string_piece(), eq(false));
+    msg.set_optional_string_piece("hello");
+    assert_that!(msg.optional_string_piece(), eq("hello"));
+    assert_that!(msg.has_optional_string_piece(), eq(true));
+}
diff --git a/rust/test/shared/edition2023_test.rs b/rust/test/shared/edition2023_test.rs
index 835ae66..9c5aeba 100644
--- a/rust/test/shared/edition2023_test.rs
+++ b/rust/test/shared/edition2023_test.rs
@@ -17,3 +17,22 @@
     assert_that!(msg.plain_field_opt().into_inner(), eq(0));
     assert_that!(msg.implicit_presence_field(), eq(0));
 }
+
+#[test]
+fn string_view_works() {
+    let mut msg = edition2023_rust_proto::EditionsMessage::new();
+    assert_that!(msg.str_view(), eq(""));
+    assert_that!(msg.has_str_view(), eq(false));
+    msg.set_str_view("hello");
+    assert_that!(msg.str_view(), eq("hello"));
+    assert_that!(msg.has_str_view(), eq(true));
+}
+
+#[test]
+fn repeated_string_view_works() {
+    let mut msg = edition2023_rust_proto::EditionsMessage::new();
+    assert_that!(msg.repeated_str_view().len(), eq(0));
+    msg.repeated_str_view_mut().push("first".into());
+    assert_that!(msg.repeated_str_view().len(), eq(1));
+    assert_that!(msg.repeated_str_view().get(0), some(eq("first")));
+}
diff --git a/src/google/protobuf/compiler/rust/accessors/accessors.cc b/src/google/protobuf/compiler/rust/accessors/accessors.cc
index 30984c9..7a057e3 100644
--- a/src/google/protobuf/compiler/rust/accessors/accessors.cc
+++ b/src/google/protobuf/compiler/rust/accessors/accessors.cc
@@ -26,11 +26,13 @@
 
 std::unique_ptr<AccessorGenerator> AccessorGeneratorFor(
     Context& ctx, const FieldDescriptor& field) {
-  // TODO: We do not support [ctype=FOO] (used to set the field
-  // type in C++ to cord or string_piece) in V0.6 API.
-  if (field.options().has_ctype()) {
+  // TODO: We do not support ctype=CORD fields or repeated
+  // ctype=STRING_PIECE fields.
+  auto ctype = field.options().ctype();
+  if (ctype == FieldOptions::CORD ||
+      (ctype == FieldOptions::STRING_PIECE && field.is_repeated())) {
     return std::make_unique<UnsupportedField>(
-        "fields with ctype not supported");
+        "fields has an unsupported ctype");
   }
 
   if (field.is_map()) {