From 3114d4b3aad34045e8c75a31857c8ee0269af7d0 Mon Sep 17 00:00:00 2001 From: "Ilya (Marshal)" Date: Sat, 29 Nov 2025 02:38:50 +0100 Subject: [PATCH 1/2] Test `get_item_unchecked` --- src/lib.rs | 66 +++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 071b997..693f92a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,38 +103,40 @@ fn map_key_cmp(a: &[u8], b: &[u8]) -> std::cmp::Ordering { fn sort_map_keys(keys: &Bound, len: usize) -> Result> { // Returns key and index. - let mut keys_str = Vec::with_capacity(len); - for i in 0..len { - let item = keys.get_item(i)?; - let key = match item.cast::() { - Ok(k) => k.to_owned(), - Err(_) => return Err(anyhow!("Map keys must be strings")), - }; - let backed_str = match PyBackedStr::try_from(key) { - Ok(bs) => bs, - Err(_) => return Err(anyhow!("Failed to convert PyString to PyBackedStr")), - }; - keys_str.push((backed_str, i)); - } + unsafe { + let mut keys_str = Vec::with_capacity(len); + for i in 0..len { + let item = keys.get_item_unchecked(i); + let key = match item.cast::() { + Ok(k) => k.to_owned(), + Err(_) => return Err(anyhow!("Map keys must be strings")), + }; + let backed_str = match PyBackedStr::try_from(key) { + Ok(bs) => bs, + Err(_) => return Err(anyhow!("Failed to convert PyString to PyBackedStr")), + }; + keys_str.push((backed_str, i)); + } - if keys_str.len() < 2 { - return Ok(keys_str); - } + if keys_str.len() < 2 { + return Ok(keys_str); + } - keys_str.sort_by(|a, b| { - // sort_unstable_by performs bad - let (s1, _) = a; - let (s2, _) = b; + keys_str.sort_by(|a, b| { + // sort_unstable_by performs bad + let (s1, _) = a; + let (s2, _) = b; - // sorted length-first by the byte representation of the string keys - if s1.len() != s2.len() { - s1.len().cmp(&s2.len()) - } else { - s1.cmp(s2) - } - }); + // sorted length-first by the byte representation of the string keys + if s1.len() != s2.len() { + s1.len().cmp(&s2.len()) + } else { + s1.cmp(s2) + } + }); - Ok(keys_str) + Ok(keys_str) + } } fn get_bytes_from_py_any<'py>(obj: &'py Bound<'py, PyAny>) -> PyResult<&'py [u8]> { @@ -354,7 +356,9 @@ where types::Array::bounded(len, w)?; for i in 0..len { - encode_dag_cbor_from_pyobject(_py, &l.get_item(i)?, w)?; + unsafe { + encode_dag_cbor_from_pyobject(_py, &l.get_item_unchecked(i), w)?; + } } Ok(()) @@ -369,7 +373,9 @@ where key.get(..) .expect("whole range is a valid string") .encode(w)?; - encode_dag_cbor_from_pyobject(_py, &values.get_item(i)?, w)?; + unsafe { + encode_dag_cbor_from_pyobject(_py, &values.get_item_unchecked(i), w)?; + } } Ok(()) From 5b52f031bd7e64504ddd9a08fb28d6c234805574 Mon Sep 17 00:00:00 2001 From: "Ilya (Marshal)" Date: Sat, 29 Nov 2025 03:17:59 +0100 Subject: [PATCH 2/2] code cleanup --- src/lib.rs | 68 +++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 693f92a..b3568f3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,40 +103,38 @@ fn map_key_cmp(a: &[u8], b: &[u8]) -> std::cmp::Ordering { fn sort_map_keys(keys: &Bound, len: usize) -> Result> { // Returns key and index. - unsafe { - let mut keys_str = Vec::with_capacity(len); - for i in 0..len { - let item = keys.get_item_unchecked(i); - let key = match item.cast::() { - Ok(k) => k.to_owned(), - Err(_) => return Err(anyhow!("Map keys must be strings")), - }; - let backed_str = match PyBackedStr::try_from(key) { - Ok(bs) => bs, - Err(_) => return Err(anyhow!("Failed to convert PyString to PyBackedStr")), - }; - keys_str.push((backed_str, i)); - } + let mut keys_str = Vec::with_capacity(len); + for i in 0..len { + let item = unsafe { keys.get_item_unchecked(i) }; + let key = match item.cast::() { + Ok(k) => k.to_owned(), + Err(_) => return Err(anyhow!("Map keys must be strings")), + }; + let backed_str = match PyBackedStr::try_from(key) { + Ok(bs) => bs, + Err(_) => return Err(anyhow!("Failed to convert PyString to PyBackedStr")), + }; + keys_str.push((backed_str, i)); + } - if keys_str.len() < 2 { - return Ok(keys_str); - } + if keys_str.len() < 2 { + return Ok(keys_str); + } - keys_str.sort_by(|a, b| { - // sort_unstable_by performs bad - let (s1, _) = a; - let (s2, _) = b; + keys_str.sort_by(|a, b| { + // sort_unstable_by performs bad + let (s1, _) = a; + let (s2, _) = b; - // sorted length-first by the byte representation of the string keys - if s1.len() != s2.len() { - s1.len().cmp(&s2.len()) - } else { - s1.cmp(s2) - } - }); + // sorted length-first by the byte representation of the string keys + if s1.len() != s2.len() { + s1.len().cmp(&s2.len()) + } else { + s1.cmp(s2) + } + }); - Ok(keys_str) - } + Ok(keys_str) } fn get_bytes_from_py_any<'py>(obj: &'py Bound<'py, PyAny>) -> PyResult<&'py [u8]> { @@ -356,9 +354,8 @@ where types::Array::bounded(len, w)?; for i in 0..len { - unsafe { - encode_dag_cbor_from_pyobject(_py, &l.get_item_unchecked(i), w)?; - } + let item = unsafe { l.get_item_unchecked(i) }; + encode_dag_cbor_from_pyobject(_py, &item, w)?; } Ok(()) @@ -373,9 +370,8 @@ where key.get(..) .expect("whole range is a valid string") .encode(w)?; - unsafe { - encode_dag_cbor_from_pyobject(_py, &values.get_item_unchecked(i), w)?; - } + let value = unsafe { values.get_item_unchecked(i) }; + encode_dag_cbor_from_pyobject(_py, &value, w)?; } Ok(())