Skip to content

Instantly share code, notes, and snippets.

@MathiasKoch
Last active July 22, 2024 11:02
Show Gist options
  • Save MathiasKoch/abb1e91fb6ff3780bea275f038bd4a61 to your computer and use it in GitHub Desktop.
Save MathiasKoch/abb1e91fb6ff3780bea275f038bd4a61 to your computer and use it in GitHub Desktop.
// Implemented by derive macro
pub(crate) trait Struct {
fn field_at(&self, index: usize) -> Option<(&'static str, Option<&'a dyn Struct>)>;
}
pub struct KeyIter<'a> {
pub(crate) struct_val: &'a dyn Struct,
pub(crate) index: usize,
pub(crate) prefix: Option<heapless::String<MAX_KEY_LEN>>,
pub(crate) inner: Option<KeyIter<'a>>,
}
impl<'a> FieldIter<'a> {
pub fn new(value: &'a dyn Struct, prefix: Option<heapless::String<MAX_KEY_LEN>>) -> Self {
FieldIter {
struct_val: value,
index: 0,
prefix,
inner: None,
}
}
}
impl<'a> Iterator for KeyIter<'a> {
type Item = heapless::String<MAX_KEY_LEN>;
fn next(&mut self) -> Option<Self::Item> {
let value = match &mut self.inner {
Some(inner) => inner.next(),
_ => None,
};
if value.is_none() {
self.inner.take();
} else {
return value;
}
let value = match self.struct_val.field_at(self.index) {
Some((field_name, None)) => {
let mut key = heapless::String::new();
if let Some(prefix) = &self.prefix {
key.push_str(prefix).unwrap();
key.push_str("/").unwrap();
}
key.push_str(field_name).unwrap();
Some(key)
}
Some((field_name, Some(s))) => {
let mut new_prefix = heapless::String::new();
if let Some(prefix) = &self.prefix {
new_prefix.push_str(prefix).unwrap();
new_prefix.push_str("/").unwrap();
}
new_prefix.push_str(field_name).unwrap();
let mut inner = KeyIter::new(s, Some(new_prefix));
let value = inner.next();
// FIXME: This does not work!
// self.inner = Some(inner);
value
}
None => None,
};
self.index += value.is_some() as usize;
value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment