[ujson] Represent arrays in rust with `ArrayVec`

The default `serde` implementations for arrays max out at 32 elements.

Signed-off-by: Chris Frantz <cfrantz@google.com>
diff --git a/sw/device/lib/testing/json/pinmux_config.h b/sw/device/lib/testing/json/pinmux_config.h
index 9cb6136..c3ad106 100644
--- a/sw/device/lib/testing/json/pinmux_config.h
+++ b/sw/device/lib/testing/json/pinmux_config.h
@@ -21,19 +21,20 @@
 // clang-format off
 
 #define STRUCT_PINMUX_INPUT_SELECTION(field, string) \
-  field(peripheral, pinmux_peripheral_in_t, 16)      \
-      field(selector, pinmux_insel_t, 16)
+    field(peripheral, pinmux_peripheral_in_t, 16)    \
+    field(selector, pinmux_insel_t, 16)
 UJSON_SERDE_STRUCT(PinmuxInputSelection, pinmux_input_selection_t,
                    STRUCT_PINMUX_INPUT_SELECTION);
 
 #define STRUCT_PINMUX_OUTPUT_SELECTION(field, string) \
-  field(mio, pinmux_mio_out_t, 16) field(selector, pinmux_outsel_t, 16)
+    field(mio, pinmux_mio_out_t, 16)                  \
+    field(selector, pinmux_outsel_t, 16)
 UJSON_SERDE_STRUCT(PinmuxOutputSelection, pinmux_output_selection_t,
                    STRUCT_PINMUX_OUTPUT_SELECTION);
 
 #define STRUCT_PINMUX_CONFIG(field, string) \
-  field(input, pinmux_input_selection_t)    \
-      field(output, pinmux_output_selection_t)
+    field(input, pinmux_input_selection_t)  \
+    field(output, pinmux_output_selection_t)
 UJSON_SERDE_STRUCT(PinmuxConfig, pinmux_config_t, STRUCT_PINMUX_CONFIG);
 
 // clang-format on
diff --git a/sw/device/lib/ujson/rust/BUILD b/sw/device/lib/ujson/rust/BUILD
index cee9711..db75770 100644
--- a/sw/device/lib/ujson/rust/BUILD
+++ b/sw/device/lib/ujson/rust/BUILD
@@ -31,6 +31,7 @@
     deps = [
         "//sw/host/opentitanlib",
         "@crate_index//:anyhow",
+        "@crate_index//:arrayvec",
         "@crate_index//:serde",
         "@crate_index//:serde_json",
     ],
diff --git a/sw/device/lib/ujson/rust/roundtrip_test.rs b/sw/device/lib/ujson/rust/roundtrip_test.rs
index 8421ec3..7109203 100644
--- a/sw/device/lib/ujson/rust/roundtrip_test.rs
+++ b/sw/device/lib/ujson/rust/roundtrip_test.rs
@@ -74,10 +74,11 @@
     fn test_matrix() -> Result<()> {
         let before = example::Matrix {
             k: [
-                [0, 1, 2, 3, 4],
-                [100, 200, 300, 400, 500],
-                [-1, -2, -3, -4, -5],
-            ],
+                [0, 1, 2, 3, 4].into(),
+                [100, 200, 300, 400, 500].into(),
+                [-1, -2, -3, -4, -5].into(),
+            ]
+            .into(),
         };
         let after = roundtrip("matrix", &serde_json::to_string(&before)?)?;
         let after = serde_json::from_str::<example::Matrix>(&after)?;
diff --git a/sw/device/lib/ujson/ujson_rust.h b/sw/device/lib/ujson/ujson_rust.h
index a50edf8..bc4ac0f 100644
--- a/sw/device/lib/ujson/ujson_rust.h
+++ b/sw/device/lib/ujson/ujson_rust.h
@@ -31,7 +31,8 @@
 #define int16_t i16
 #define int8_t i8
 
-#define RUST_DEFAULT_DERIVE Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq
+#define RUST_DEFAULT_DERIVE \
+  Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq
 
 // clang-format off
 rust_attr[allow(unused_imports)]
@@ -43,9 +44,9 @@
 #define ujson_struct_field_array(t_, sz_, ...) \
     OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
     ( /*then*/ \
-        [t_; sz_]\
+        arrayvec::ArrayVec<OT_EXPAND(t_, sz_)> \
     , /*else*/ \
-        [OT_OBSTRUCT(ujson_struct_field_array_indirect)()(t_, __VA_ARGS__); sz_] \
+        arrayvec::ArrayVec<OT_OBSTRUCT(ujson_struct_field_array_indirect)()(t_, __VA_ARGS__), sz_> \
     ) /*endif*/
 
 #define ujson_struct_field(name_, type_, ...) \
diff --git a/sw/host/opentitanlib/BUILD b/sw/host/opentitanlib/BUILD
index 09f48ec..4620172 100644
--- a/sw/host/opentitanlib/BUILD
+++ b/sw/host/opentitanlib/BUILD
@@ -191,6 +191,7 @@
     deps = [
         "//sw/host/opentitanlib/bindgen",
         "@crate_index//:anyhow",
+        "@crate_index//:arrayvec",
         "@crate_index//:bitflags",
         "@crate_index//:bitvec",
         "@crate_index//:byteorder",
diff --git a/sw/host/opentitanlib/src/test_utils/pinmux_config.rs b/sw/host/opentitanlib/src/test_utils/pinmux_config.rs
index b5fbad3..55973e1 100644
--- a/sw/host/opentitanlib/src/test_utils/pinmux_config.rs
+++ b/sw/host/opentitanlib/src/test_utils/pinmux_config.rs
@@ -56,7 +56,7 @@
         let mut i = 0;
         while i < len {
             let mut config = Self::default();
-            for j in 0..config.input.peripheral.len() {
+            for _ in 0..config.input.peripheral.capacity() {
                 let (ik, iv) = inputs
                     .as_mut()
                     .and_then(|i| i.next())
@@ -65,10 +65,10 @@
                     .as_mut()
                     .and_then(|i| i.next())
                     .unwrap_or((&df_ok, &df_ov));
-                config.input.peripheral[j] = *ik;
-                config.input.selector[j] = *iv;
-                config.output.mio[j] = *ok;
-                config.output.selector[j] = *ov;
+                config.input.peripheral.push(*ik);
+                config.input.selector.push(*iv);
+                config.output.mio.push(*ok);
+                config.output.selector.push(*ov);
                 i += 1;
             }
             TestCommand::PinmuxConfig.send(uart)?;
diff --git a/sw/host/tests/rom/e2e_chip_specific_startup/BUILD b/sw/host/tests/rom/e2e_chip_specific_startup/BUILD
index 092e035..4986e11 100644
--- a/sw/host/tests/rom/e2e_chip_specific_startup/BUILD
+++ b/sw/host/tests/rom/e2e_chip_specific_startup/BUILD
@@ -25,6 +25,7 @@
     deps = [
         "//sw/host/opentitanlib",
         "@crate_index//:anyhow",
+        "@crate_index//:arrayvec",
         "@crate_index//:humantime",
         "@crate_index//:log",
         "@crate_index//:serde",