floss: Add ascii_to_string

Add a function in topshim/btif to convert an ascii slice (&[u8]) into
a Rust String. This refactors the previous conversion for bt_bdname_t to
use String::from_utf8 instead of using str.

Bug: 197021037
Tag: #floss
Test: Rust unit tests
Change-Id: I84e989759a2d29747f4fbaf128a84cc83fca63b4
diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs
index 5d6c225..702edc0 100644
--- a/system/gd/rust/topshim/src/btif.rs
+++ b/system/gd/rust/topshim/src/btif.rs
@@ -172,6 +172,19 @@
     Unknown = 0xff,
 }
 
+fn ascii_to_string(data: &[u8], length: usize) -> String {
+    // We need to reslice data because from_utf8 tries to interpret the
+    // whole slice and not just what is before the null terminated portion
+    let ascii = data
+        .iter()
+        .enumerate()
+        .take_while(|&(pos, &c)| c != 0 && pos < length)
+        .map(|(_pos, &x)| x.clone())
+        .collect::<Vec<u8>>();
+
+    return String::from_utf8(ascii).unwrap_or_default();
+}
+
 impl From<bindings::bt_status_t> for BtStatus {
     fn from(item: bindings::bt_status_t) -> Self {
         match BtStatus::from_u32(item) {
@@ -213,12 +226,7 @@
 
 impl From<bindings::bt_bdname_t> for String {
     fn from(item: bindings::bt_bdname_t) -> Self {
-        // We need to reslice item.name because from_utf8 tries to interpret the
-        // whole slice and not just what is before the null terminated portion
-        let ascii =
-            item.name.iter().take_while(|&c| *c != 0).map(|x| x.clone()).collect::<Vec<u8>>();
-
-        return std::str::from_utf8(ascii.as_slice()).unwrap_or("").to_string();
+        ascii_to_string(&item.name, item.name.len())
     }
 }