From b0184d91da52913f392693b65aab73efdd19899b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Thu, 11 Jul 2024 12:57:39 +0200 Subject: [PATCH 1/4] indices: add from --- miniconf/src/node.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/miniconf/src/node.rs b/miniconf/src/node.rs index b70d6fc0..52683d2b 100644 --- a/miniconf/src/node.rs +++ b/miniconf/src/node.rs @@ -276,6 +276,12 @@ impl From> for [usize; D] { } } +impl From for Indices { + fn from(value: T) -> Self { + Self(value) + } +} + impl<'a, T: AsRef<[usize]> + ?Sized> IntoKeys for &'a Indices { type IntoKeys = KeysIter>>; fn into_keys(self) -> Self::IntoKeys { From 5664a671bbe0f3aaea0b212dff18e66783ad2e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Thu, 11 Jul 2024 14:06:18 +0200 Subject: [PATCH 2/4] cli: updates --- miniconf_cli/src/lib.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/miniconf_cli/src/lib.rs b/miniconf_cli/src/lib.rs index c45ab0a8..40b8774f 100644 --- a/miniconf_cli/src/lib.rs +++ b/miniconf_cli/src/lib.rs @@ -40,7 +40,7 @@ async fn awrite(mut write: W, buf: &[u8]) -> Result<(), Error { Fmt(core::fmt::Error), Traversal(miniconf::Traversal), - Serialize(serde_json_core::ser::Error), + Serialize(usize, serde_json_core::ser::Error), Io(I), } @@ -53,9 +53,9 @@ impl From for Error { impl From> for Error { fn from(value: miniconf::Error) -> Self { match value { - miniconf::Error::Inner(_depth, e) => Self::Serialize(e), + miniconf::Error::Inner(depth, e) => Self::Serialize(depth, e), miniconf::Error::Traversal(e) => Self::Traversal(e), - miniconf::Error::Finalization(_) => unreachable!(), + miniconf::Error::Finalization(e) => Self::Serialize(0, e), _ => unimplemented!(), } } @@ -99,17 +99,17 @@ where } fn push(&self, path: &str) -> Result<(Self, Node), Traversal> { - let (key, node) = M::transcode(self.key.chain(path.split(SEPARATOR)))?; + let (key, node) = M::transcode(self.key.chain(&Path::<_, SEPARATOR>::from(path)))?; Ok((Self::new(key), node)) } fn pop(&self, levels: usize) -> Result<(Self, Node), Traversal> { let (idx, node) = M::transcode::, _>(self.key)?; - if node.depth() < levels { - Err(Traversal::TooShort(node.depth())) - } else { - let (key, node) = M::transcode(idx[..node.depth() - levels].iter().copied())?; + if let Some(idx) = idx.get(..node.depth() - levels) { + let (key, node) = M::transcode(&Indices::from(idx))?; Ok((Self::new(key), node)) + } else { + Err(Traversal::TooShort(node.depth())) } } @@ -165,6 +165,7 @@ where { let def = M::default(); for keys in M::nodes::().root(self.key)? { + // Slight abuse of TooLong for "keys to long for packed" let (keys, node) = keys.map_err(|depth| miniconf::Error::Traversal(Traversal::TooLong(depth)))?; debug_assert!(node.is_leaf()); @@ -235,11 +236,11 @@ where ret => &buf[..ret?], }; if yafnv::fnv1a::(def) == check { - awrite(&mut write, " (default)\n".as_bytes()).await?; + awrite(&mut write, " [default]\n".as_bytes()).await?; } else { - awrite(&mut write, " (default: ".as_bytes()).await?; + awrite(&mut write, " [default: ".as_bytes()).await?; awrite(&mut write, def).await?; - awrite(&mut write, ")\n".as_bytes()).await?; + awrite(&mut write, "]\n".as_bytes()).await?; } } Ok(()) @@ -289,21 +290,22 @@ mod tests { let mut stdout = embedded_io_adapters::tokio_1::FromTokio::new(tokio::io::stdout()); let mut menu = Menu::::default(); s.c = Some(8); - menu.enter("b/0").unwrap(); + menu.enter("/b").unwrap(); + menu.enter("/0").unwrap(); menu.set(&mut s, b"1234").unwrap(); menu.exit(2).unwrap(); - menu.push("f/1/e").unwrap().0.set(&mut s, b"9").unwrap(); + menu.push("/f/1/e").unwrap().0.set(&mut s, b"9").unwrap(); let paths: Vec> = menu.list().unwrap().map(Result::unwrap).collect(); stdout .write_all(format!("{:?}\n", paths).as_bytes()) .await .unwrap(); menu.dump(&s, &mut stdout, &mut buf).await.unwrap(); - menu.enter("f").unwrap(); + menu.enter("/f").unwrap(); menu.dump(&s, &mut stdout, &mut buf).await.unwrap(); menu.exit(1).unwrap(); - menu.push("c").unwrap().0.reset(&mut s, &mut buf).unwrap(); - menu.push("b").unwrap().0.reset(&mut s, &mut buf).unwrap(); + menu.push("/c").unwrap().0.reset(&mut s, &mut buf).unwrap(); + menu.push("/b").unwrap().0.reset(&mut s, &mut buf).unwrap(); menu.dump(&s, &mut stdout, &mut buf).await.unwrap(); } } From c0b05697b094862acdb40c17aac1e5ed1be5a5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Fri, 12 Jul 2024 16:22:29 +0200 Subject: [PATCH 3/4] cli: remove unnecessary impls --- miniconf_cli/src/lib.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/miniconf_cli/src/lib.rs b/miniconf_cli/src/lib.rs index 40b8774f..ea758010 100644 --- a/miniconf_cli/src/lib.rs +++ b/miniconf_cli/src/lib.rs @@ -16,20 +16,10 @@ use miniconf::{ struct WriteWrap(T); impl fmt::Write for WriteWrap { - fn write_char(&mut self, c: char) -> fmt::Result { - let mut buf = [0; 4]; - self.write_str(c.encode_utf8(&mut buf)) - } - fn write_str(&mut self, s: &str) -> fmt::Result { self.0.write_all(s.as_bytes()).or(Err(fmt::Error))?; Ok(()) } - - fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { - self.0.write_fmt(args).or(Err(fmt::Error))?; - Ok(()) - } } async fn awrite(mut write: W, buf: &[u8]) -> Result<(), Error> { From 142c7cc90f73e6fbdd61ee7a32e96d42e2693dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Tue, 16 Jul 2024 17:45:34 +0200 Subject: [PATCH 4/4] introduce shorthand traits for owned deserialization --- miniconf/src/json_core.rs | 4 ++++ miniconf/src/postcard.rs | 4 ++++ miniconf/src/tree.rs | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/miniconf/src/json_core.rs b/miniconf/src/json_core.rs index c4d541c4..eb9d9897 100644 --- a/miniconf/src/json_core.rs +++ b/miniconf/src/json_core.rs @@ -100,3 +100,7 @@ impl<'de, T: TreeSerialize + TreeDeserialize<'de, Y> + ?Sized, const Y: usize Ok(ser.end()) } } + +/// Shorthand for owned deserialization through [`JsonCoreSlash`]. +pub trait JsonCoreSlashOwned: for<'de> JsonCoreSlash<'de, Y> {} +impl JsonCoreSlashOwned for T where T: for<'de> JsonCoreSlash<'de, Y> {} diff --git a/miniconf/src/postcard.rs b/miniconf/src/postcard.rs index ddbd8253..b75fba45 100644 --- a/miniconf/src/postcard.rs +++ b/miniconf/src/postcard.rs @@ -69,3 +69,7 @@ impl<'de, T: TreeSerialize + TreeDeserialize<'de, Y> + ?Sized, const Y: usize ser.output.finalize().map_err(Error::Finalization) } } + +/// Shorthand for owned [`Postcard`]. +pub trait PostcardOwned: for<'de> Postcard<'de, Y> {} +impl PostcardOwned for T where T: for<'de> Postcard<'de, Y> {} diff --git a/miniconf/src/tree.rs b/miniconf/src/tree.rs index ee349a27..b294020c 100644 --- a/miniconf/src/tree.rs +++ b/miniconf/src/tree.rs @@ -619,3 +619,7 @@ pub trait TreeDeserialize<'de, const Y: usize = 1>: TreeKey { K: Keys, D: Deserializer<'de>; } + +/// Shorthand for owned deserialization through [`TreeDeserialize`]. +pub trait TreeDeserializeOwned: for<'de> TreeDeserialize<'de, Y> {} +impl TreeDeserializeOwned for T where T: for<'de> TreeDeserialize<'de, Y> {}