All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ariel Miculas <amiculas@cisco.com>
To: rust-for-linux@vger.kernel.org
Cc: Miguel Ojeda <ojeda@kernel.org>
Subject: [PATCH 35/80] rust: test `serde` support
Date: Fri,  9 Jun 2023 09:30:33 +0300	[thread overview]
Message-ID: <20230609063118.24852-36-amiculas@cisco.com> (raw)
In-Reply-To: <20230609063118.24852-1-amiculas@cisco.com>

From: Miguel Ojeda <ojeda@kernel.org>

A trivial example based on `serde`'s `example-format' [1].

It contains both a in-`kernel` data format later used by
the kernel module, as well as a local data format in
the module.

The kernel module gives an output such as:

    [    0.801425] rust_serde: Rust serde sample (init)
    [    0.801634] rust_serde:             original = S { a: (), b: false, c: true, d: () }
    [    0.802079] rust_serde:           serialized = [2, 0, 1, 0, 1, 1, 0, 3]
    [    0.802506] rust_serde:         deserialized = S { a: (), b: false, c: true, d: () }
    [    0.802718] rust_serde:   serialized (local) = [2, 0, 1, 42, 1, 43, 0, 3]
    [    0.802895] rust_serde: deserialized (local) = S { a: (), b: false, c: true, d: () }
    [    0.808954] rust_serde: Rust serde sample (exit)

Note that this is just a quick draft/hack to check the previous
commits work. It is not intended to be merged at all.

Link: https://github.com/serde-rs/example-format [1]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
 rust/kernel/lib.rs                      |   1 +
 rust/kernel/test_serde.rs               |  26 ++
 rust/kernel/test_serde/de.rs            | 442 ++++++++++++++++++++++
 rust/kernel/test_serde/error.rs         |  73 ++++
 rust/kernel/test_serde/ser.rs           | 469 ++++++++++++++++++++++++
 samples/rust/Kconfig                    |   8 +
 samples/rust/Makefile                   |   1 +
 samples/rust/local_data_format/de.rs    | 422 +++++++++++++++++++++
 samples/rust/local_data_format/error.rs |  73 ++++
 samples/rust/local_data_format/ser.rs   | 443 ++++++++++++++++++++++
 samples/rust/rust_serde.rs              |  73 ++++
 11 files changed, 2031 insertions(+)
 create mode 100644 rust/kernel/test_serde.rs
 create mode 100644 rust/kernel/test_serde/de.rs
 create mode 100644 rust/kernel/test_serde/error.rs
 create mode 100644 rust/kernel/test_serde/ser.rs
 create mode 100644 samples/rust/local_data_format/de.rs
 create mode 100644 samples/rust/local_data_format/error.rs
 create mode 100644 samples/rust/local_data_format/ser.rs
 create mode 100644 samples/rust/rust_serde.rs

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 08f67833afcf..a94fb784d576 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -178,3 +178,4 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
 ///
 /// [`PAGE_SHIFT`]: ../../../include/asm-generic/page.h
 pub const PAGE_SIZE: usize = 1 << bindings::PAGE_SHIFT;
+pub mod test_serde;
diff --git a/rust/kernel/test_serde.rs b/rust/kernel/test_serde.rs
new file mode 100644
index 000000000000..012bf58213a8
--- /dev/null
+++ b/rust/kernel/test_serde.rs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+//! Test `serde`.
+//!
+//! It contains a data format used by the `rust_serde` sample, as well
+//! as a quick check that `serde_derive` works in the `kernel` crate too.
+
+#![allow(missing_docs)]
+
+mod de;
+mod error;
+mod ser;
+
+pub use de::{from_bytes, Deserializer};
+pub use error::{Error, Result};
+pub use ser::{to_vec, Serializer};
+
+use serde_derive::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize, Debug)]
+pub struct S {
+    a: (),
+    b: bool,
+    c: bool,
+    d: (),
+}
diff --git a/rust/kernel/test_serde/de.rs b/rust/kernel/test_serde/de.rs
new file mode 100644
index 000000000000..84c98d1c1c66
--- /dev/null
+++ b/rust/kernel/test_serde/de.rs
@@ -0,0 +1,442 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+// Copyright 2018 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::error::{Error, Result};
+use serde::de::{self, Deserialize, DeserializeSeed, SeqAccess, Visitor};
+
+pub struct Deserializer<'de> {
+    // This string starts with the input data and characters are truncated off
+    // the beginning as data is parsed.
+    input: &'de [u8],
+}
+
+impl<'de> Deserializer<'de> {
+    // By convention, `Deserializer` constructors are named like `from_xyz`.
+    // That way basic use cases are satisfied by something like
+    // `serde_json::from_str(...)` while advanced use cases that require a
+    // deserializer can make one with `serde_json::Deserializer::from_str(...)`.
+    #[allow(clippy::should_implement_trait)]
+    pub fn from_bytes(input: &'de [u8]) -> Self {
+        Deserializer { input }
+    }
+}
+
+// By convention, the public API of a Serde deserializer is one or more
+// `from_xyz` methods such as `from_str`, `from_bytes`, or `from_reader`
+// depending on what Rust types the deserializer is able to consume as input.
+//
+// This basic deserializer supports only `from_str`.
+pub fn from_bytes<'a, T>(s: &'a [u8]) -> Result<T>
+where
+    T: Deserialize<'a>,
+{
+    let mut deserializer = Deserializer::from_bytes(s);
+    let t = T::deserialize(&mut deserializer)?;
+    if deserializer.input.is_empty() {
+        Ok(t)
+    } else {
+        Err(Error::TrailingCharacters)
+    }
+}
+
+// SERDE IS NOT A PARSING LIBRARY. This impl block defines a few basic parsing
+// functions from scratch. More complicated formats may wish to use a dedicated
+// parsing library to help implement their Serde deserializer.
+impl<'de> Deserializer<'de> {
+    // Look at the first character in the input without consuming it.
+    fn peek_byte(&mut self) -> Result<u8> {
+        self.input.iter().next().ok_or(Error::Eof).map(|v| *v)
+    }
+
+    // Consume the first character in the input.
+    fn next_byte(&mut self) -> Result<u8> {
+        let ch = self.peek_byte()?;
+        self.input = &self.input[1..];
+        Ok(ch)
+    }
+
+    // Parse the JSON identifier `true` or `false`.
+    fn parse_bool(&mut self) -> Result<bool> {
+        if self.input.starts_with(&[1]) {
+            self.input = &self.input[1..];
+            match self.next_byte()? {
+                0 => Ok(false),
+                1 => Ok(true),
+                _ => Err(Error::InvalidBooleanValue),
+            }
+        } else {
+            Err(Error::ExpectedBoolean)
+        }
+    }
+
+    // Parse a group of decimal digits as an unsigned integer of type T.
+    //
+    // This implementation is a bit too lenient, for example `001` is not
+    // allowed in JSON. Also the various arithmetic operations can overflow and
+    // panic or return bogus data. But it is good enough for example code!
+    fn parse_unsigned<T>(&mut self) -> Result<T> {
+        unimplemented!()
+    }
+
+    // Parse a possible minus sign followed by a group of decimal digits as a
+    // signed integer of type T.
+    fn parse_signed<T>(&mut self) -> Result<T> {
+        // Optional minus sign, delegate to `parse_unsigned`, negate if negative.
+        unimplemented!()
+    }
+}
+
+impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
+    type Error = Error;
+
+    // Look at the input data to decide what Serde data model type to
+    // deserialize as. Not all data formats are able to support this operation.
+    // Formats that support `deserialize_any` are known as self-describing.
+    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        match self.peek_byte()? {
+            0 => self.deserialize_unit(visitor),
+            1 => self.deserialize_bool(visitor),
+            2 => self.deserialize_map(visitor),
+            _ => Err(Error::Syntax),
+        }
+    }
+
+    // Uses the `parse_bool` parsing function defined above to read the JSON
+    // identifier `true` or `false` from the input.
+    //
+    // Parsing refers to looking at the input and deciding that it contains the
+    // JSON value `true` or `false`.
+    //
+    // Deserialization refers to mapping that JSON value into Serde's data
+    // model by invoking one of the `Visitor` methods. In the case of JSON and
+    // bool that mapping is straightforward so the distinction may seem silly,
+    // but in other cases Deserializers sometimes perform non-obvious mappings.
+    // For example the TOML format has a Datetime type and Serde's data model
+    // does not. In the `toml` crate, a Datetime in the input is deserialized by
+    // mapping it to a Serde data model "struct" type with a special name and a
+    // single field containing the Datetime represented as a string.
+    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_bool(self.parse_bool()?)
+    }
+
+    // The `parse_signed` function is generic over the integer type `T` so here
+    // it is invoked with `T=i8`. The next 8 methods are similar.
+    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i8(self.parse_signed()?)
+    }
+
+    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i16(self.parse_signed()?)
+    }
+
+    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i32(self.parse_signed()?)
+    }
+
+    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i64(self.parse_signed()?)
+    }
+
+    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u8(self.parse_unsigned()?)
+    }
+
+    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u16(self.parse_unsigned()?)
+    }
+
+    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u32(self.parse_unsigned()?)
+    }
+
+    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u64(self.parse_unsigned()?)
+    }
+
+    // The `Serializer` implementation on the previous page serialized chars as
+    // single-character strings so handle that representation here.
+    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // Refer to the "Understanding deserializer lifetimes" page for information
+    // about the three deserialization flavors of strings in Serde.
+    fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // The `Serializer` implementation on the previous page serialized byte
+    // arrays as JSON arrays of bytes. Handle that representation here.
+    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // An absent optional is represented as the JSON `null` and a present
+    // optional is represented as just the contained value.
+    //
+    // As commented in `Serializer` implementation, this is a lossy
+    // representation. For example the values `Some(())` and `None` both
+    // serialize as just `null`. Unfortunately this is typically what people
+    // expect when working with JSON. Other formats are encouraged to behave
+    // more intelligently if possible.
+    fn deserialize_option<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // In Serde, unit means an anonymous value containing no data.
+    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        if self.input.starts_with(&[0]) {
+            self.input = &self.input[1..];
+            visitor.visit_unit()
+        } else {
+            Err(Error::ExpectedNull)
+        }
+    }
+
+    // Unit struct means a named value containing no data.
+    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_unit(visitor)
+    }
+
+    // As is done here, serializers are encouraged to treat newtype structs as
+    // insignificant wrappers around the data they contain. That means not
+    // parsing anything other than the contained value.
+    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_newtype_struct(self)
+    }
+
+    // Deserialization of compound types like sequences and maps happens by
+    // passing the visitor an "Access" object that gives it the ability to
+    // iterate through the data contained in the sequence.
+    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // Tuples look just like sequences in JSON. Some formats may be able to
+    // represent tuples more efficiently.
+    //
+    // As indicated by the length parameter, the `Deserialize` implementation
+    // for a tuple in the Serde data model is required to know the length of the
+    // tuple before even looking at the input data.
+    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_seq(visitor)
+    }
+
+    // Tuple structs look just like sequences in JSON.
+    fn deserialize_tuple_struct<V>(
+        self,
+        _name: &'static str,
+        _len: usize,
+        visitor: V,
+    ) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_seq(visitor)
+    }
+
+    // Much like `deserialize_seq` but calls the visitors `visit_map` method
+    // with a `MapAccess` implementation, rather than the visitor's `visit_seq`
+    // method with a `SeqAccess` implementation.
+    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        // Parse the opening brace of the map.
+        if self.next_byte()? == 2 {
+            // Give the visitor access to each entry of the map.
+            let value = visitor.visit_seq(StructFieldsVisitor::new(self))?;
+            // Parse the closing brace of the map.
+            if self.next_byte()? == 3 {
+                Ok(value)
+            } else {
+                Err(Error::ExpectedMapEnd)
+            }
+        } else {
+            Err(Error::ExpectedMap)
+        }
+    }
+
+    // Structs look just like maps in JSON.
+    //
+    // Notice the `fields` parameter - a "struct" in the Serde data model means
+    // that the `Deserialize` implementation is required to know what the fields
+    // are before even looking at the input data. Any key-value pairing in which
+    // the fields cannot be known ahead of time is probably a map.
+    fn deserialize_struct<V>(
+        self,
+        _name: &'static str,
+        _fields: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_map(visitor)
+    }
+
+    fn deserialize_enum<V>(
+        self,
+        _name: &'static str,
+        _variants: &'static [&'static str],
+        _visitor: V,
+    ) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // An identifier in Serde is the type that identifies a field of a struct or
+    // the variant of an enum. In JSON, struct fields and enum variants are
+    // represented as strings. In other formats they may be represented as
+    // numeric indices.
+    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_str(visitor)
+    }
+
+    // Like `deserialize_any` but indicates to the `Deserializer` that it makes
+    // no difference which `Visitor` method is called because the data is
+    // ignored.
+    //
+    // Some deserializers are able to implement this more efficiently than
+    // `deserialize_any`, for example by rapidly skipping over matched
+    // delimiters without paying close attention to the data in between.
+    //
+    // Some formats are not able to implement this at all. Formats that can
+    // implement `deserialize_any` and `deserialize_ignored_any` are known as
+    // self-describing.
+    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_any(visitor)
+    }
+}
+
+struct StructFieldsVisitor<'a, 'de> {
+    de: &'a mut Deserializer<'de>,
+}
+
+impl<'a, 'de> StructFieldsVisitor<'a, 'de> {
+    fn new(de: &'a mut Deserializer<'de>) -> Self {
+        StructFieldsVisitor { de }
+    }
+}
+
+impl<'de, 'a> SeqAccess<'de> for StructFieldsVisitor<'a, 'de> {
+    type Error = Error;
+
+    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+    where
+        T: DeserializeSeed<'de>,
+    {
+        // Check if there are no more elements.
+        if self.de.peek_byte()? == 3 {
+            return Ok(None);
+        }
+        // Deserialize an array element.
+        seed.deserialize(&mut *self.de).map(Some)
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[test]
+fn test_struct() {
+    use serde_derive::Deserialize;
+
+    #[derive(Deserialize, PartialEq, Debug)]
+    struct Test {
+        a: (),
+        b: bool,
+    }
+
+    let j = &[2, 0, 1, 0, 3];
+    let expected = Test {
+        a: (),
+        b: false,
+    };
+    assert_eq!(expected, from_bytes(j).unwrap());
+}
\ No newline at end of file
diff --git a/rust/kernel/test_serde/error.rs b/rust/kernel/test_serde/error.rs
new file mode 100644
index 000000000000..a1eb3720ce67
--- /dev/null
+++ b/rust/kernel/test_serde/error.rs
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+// Copyright 2018 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::fmt::{self, Display};
+use serde::{de, ser};
+
+pub type Result<T> = crate::error::Result<T, Error>;
+
+// This is a bare-bones implementation. A real library would provide additional
+// information in its error type, for example the line and column at which the
+// error occurred, the byte offset into the input, or the current key being
+// processed.
+#[derive(Debug)]
+pub enum Error {
+    // One or more variants that can be created by data structures through the
+    // `ser::Error` and `de::Error` traits. For example the Serialize impl for
+    // Mutex<T> might return an error because the mutex is poisoned, or the
+    // Deserialize impl for a struct may return an error because a required
+    // field is missing.
+    Message,
+
+    // Zero or more variants that can be created directly by the Serializer and
+    // Deserializer without going through `ser::Error` and `de::Error`. These
+    // are specific to the format, in this case JSON.
+    Eof,
+    Syntax,
+    ExpectedBoolean,
+    InvalidBooleanValue,
+    ExpectedInteger,
+    ExpectedString,
+    ExpectedNull,
+    ExpectedArray,
+    ExpectedArrayComma,
+    ExpectedArrayEnd,
+    ExpectedMap,
+    ExpectedMapColon,
+    ExpectedMapComma,
+    ExpectedMapEnd,
+    ExpectedEnum,
+    TrailingCharacters,
+}
+
+impl ser::Error for Error {
+    fn custom<T: Display>(_msg: T) -> Self {
+        Error::Message
+    }
+}
+
+impl de::Error for Error {
+    fn custom<T: Display>(_msg: T) -> Self {
+        Error::Message
+    }
+}
+
+impl Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Error::Message => write!(f, "message"),
+            Error::Eof => f.write_str("unexpected end of input"),
+            /* and so forth */
+            _ => unimplemented!(),
+        }
+    }
+}
+
+//impl core::error::Error for Error {}
diff --git a/rust/kernel/test_serde/ser.rs b/rust/kernel/test_serde/ser.rs
new file mode 100644
index 000000000000..56abe7095a5f
--- /dev/null
+++ b/rust/kernel/test_serde/ser.rs
@@ -0,0 +1,469 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+// Copyright 2018 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::error::{Error, Result};
+use alloc::vec::Vec;
+use serde::ser::{self, Serialize};
+
+pub struct Serializer {
+    // This string starts empty and JSON is appended as values are serialized.
+    output: Vec<u8>,
+}
+
+// By convention, the public API of a Serde serializer is one or more `to_abc`
+// functions such as `to_string`, `to_bytes`, or `to_writer` depending on what
+// Rust types the serializer is able to produce as output.
+//
+// This basic serializer supports only `to_string`.
+pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
+where
+    T: Serialize,
+{
+    let mut serializer = Serializer { output: Vec::new() };
+    value.serialize(&mut serializer)?;
+    Ok(serializer.output)
+}
+
+impl<'a> ser::Serializer for &'a mut Serializer {
+    // The output type produced by this `Serializer` during successful
+    // serialization. Most serializers that produce text or binary output should
+    // set `Ok = ()` and serialize into an `io::Write` or buffer contained
+    // within the `Serializer` instance, as happens here. Serializers that build
+    // in-memory data structures may be simplified by using `Ok` to propagate
+    // the data structure around.
+    type Ok = ();
+
+    // The error type when some error occurs during serialization.
+    type Error = Error;
+
+    // Associated types for keeping track of additional state while serializing
+    // compound data structures like sequences and maps. In this case no
+    // additional state is required beyond what is already stored in the
+    // Serializer struct.
+    type SerializeSeq = Self;
+    type SerializeTuple = Self;
+    type SerializeTupleStruct = Self;
+    type SerializeTupleVariant = Self;
+    type SerializeMap = Self;
+    type SerializeStruct = Self;
+    type SerializeStructVariant = Self;
+
+    // Here we go with the simple methods. The following 12 methods receive one
+    // of the primitive types of the data model and map it to JSON by appending
+    // into the output string.
+    fn serialize_bool(self, v: bool) -> Result<()> {
+        self.output.try_push(1).unwrap();
+        self.output.try_push(if v { 1 } else { 0 }).unwrap();
+        Ok(())
+    }
+
+    // JSON does not distinguish between different sizes of integers, so all
+    // signed integers will be serialized the same and all unsigned integers
+    // will be serialized the same. Other formats, especially compact binary
+    // formats, may need independent logic for the different sizes.
+    fn serialize_i8(self, v: i8) -> Result<()> {
+        self.serialize_i64(i64::from(v))
+    }
+
+    fn serialize_i16(self, v: i16) -> Result<()> {
+        self.serialize_i64(i64::from(v))
+    }
+
+    fn serialize_i32(self, v: i32) -> Result<()> {
+        self.serialize_i64(i64::from(v))
+    }
+
+    // Not particularly efficient but this is example code anyway. A more
+    // performant approach would be to use the `itoa` crate.
+    fn serialize_i64(self, _v: i64) -> Result<()> {
+        unimplemented!();
+    }
+
+    fn serialize_u8(self, v: u8) -> Result<()> {
+        self.serialize_u64(u64::from(v))
+    }
+
+    fn serialize_u16(self, v: u16) -> Result<()> {
+        self.serialize_u64(u64::from(v))
+    }
+
+    fn serialize_u32(self, v: u32) -> Result<()> {
+        self.serialize_u64(u64::from(v))
+    }
+
+    fn serialize_u64(self, _v: u64) -> Result<()> {
+        unimplemented!();
+    }
+
+    // Serialize a char as a single-character string. Other formats may
+    // represent this differently.
+    fn serialize_char(self, _v: char) -> Result<()> {
+        unimplemented!();
+    }
+
+    // This only works for strings that don't require escape sequences but you
+    // get the idea. For example it would emit invalid JSON if the input string
+    // contains a '"' character.
+    fn serialize_str(self, _v: &str) -> Result<()> {
+        unimplemented!();
+    }
+
+    // Serialize a byte array as an array of bytes. Could also use a base64
+    // string here. Binary formats will typically represent byte arrays more
+    // compactly.
+    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
+        use serde::ser::SerializeSeq;
+        let mut seq = self.serialize_seq(Some(v.len()))?;
+        for byte in v {
+            seq.serialize_element(byte)?;
+        }
+        seq.end()
+    }
+
+    // An absent optional is represented as the JSON `null`.
+    fn serialize_none(self) -> Result<()> {
+        self.serialize_unit()
+    }
+
+    // A present optional is represented as just the contained value. Note that
+    // this is a lossy representation. For example the values `Some(())` and
+    // `None` both serialize as just `null`. Unfortunately this is typically
+    // what people expect when working with JSON. Other formats are encouraged
+    // to behave more intelligently if possible.
+    fn serialize_some<T>(self, value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        value.serialize(self)
+    }
+
+    // In Serde, unit means an anonymous value containing no data. Map this to
+    // JSON as `null`.
+    fn serialize_unit(self) -> Result<()> {
+        self.output.try_push(0).unwrap();
+        Ok(())
+    }
+
+    // Unit struct means a named value containing no data. Again, since there is
+    // no data, map this to JSON as `null`. There is no need to serialize the
+    // name in most formats.
+    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+        self.serialize_unit()
+    }
+
+    // When serializing a unit variant (or any other kind of variant), formats
+    // can choose whether to keep track of it by index or by name. Binary
+    // formats typically use the index of the variant and human-readable formats
+    // typically use the name.
+    fn serialize_unit_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        variant: &'static str,
+    ) -> Result<()> {
+        self.serialize_str(variant)
+    }
+
+    // As is done here, serializers are encouraged to treat newtype structs as
+    // insignificant wrappers around the data they contain.
+    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        value.serialize(self)
+    }
+
+    // Note that newtype variant (and all of the other variant serialization
+    // methods) refer exclusively to the "externally tagged" enum
+    // representation.
+    //
+    // Serialize this to JSON in externally tagged form as `{ NAME: VALUE }`.
+    fn serialize_newtype_variant<T>(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _value: &T,
+    ) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    // Now we get to the serialization of compound types.
+    //
+    // The start of the sequence, each value, and the end are three separate
+    // method calls. This one is responsible only for serializing the start,
+    // which in JSON is `[`.
+    //
+    // The length of the sequence may or may not be known ahead of time. This
+    // doesn't make a difference in JSON because the length is not represented
+    // explicitly in the serialized form. Some serializers may only be able to
+    // support sequences for which the length is known up front.
+    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+        unimplemented!();
+    }
+
+    // Tuples look just like sequences in JSON. Some formats may be able to
+    // represent tuples more efficiently by omitting the length, since tuple
+    // means that the corresponding `Deserialize implementation will know the
+    // length without needing to look at the serialized data.
+    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+        self.serialize_seq(Some(len))
+    }
+
+    // Tuple structs look just like sequences in JSON.
+    fn serialize_tuple_struct(
+        self,
+        _name: &'static str,
+        len: usize,
+    ) -> Result<Self::SerializeTupleStruct> {
+        self.serialize_seq(Some(len))
+    }
+
+    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }`. Again
+    // this method is only responsible for the externally tagged representation.
+    fn serialize_tuple_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleVariant> {
+        unimplemented!();
+    }
+
+    // Maps are represented in JSON as `{ K: V, K: V, ... }`.
+    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+        self.output.try_push(2).unwrap();
+        Ok(self)
+    }
+
+    // Structs look just like maps in JSON. In particular, JSON requires that we
+    // serialize the field names of the struct. Other formats may be able to
+    // omit the field names when serializing structs because the corresponding
+    // Deserialize implementation is required to know what the keys are without
+    // looking at the serialized data.
+    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+        self.serialize_map(Some(len))
+    }
+
+    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }`.
+    // This is the externally tagged representation.
+    fn serialize_struct_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeStructVariant> {
+        unimplemented!();
+    }
+
+    fn collect_str<T: ?Sized>(self, _: &T) -> Result<()>
+    where
+        T: core::fmt::Display,
+    {
+        unimplemented!()
+    }
+}
+
+// The following 7 impls deal with the serialization of compound types like
+// sequences and maps. Serialization of such types is begun by a Serializer
+// method and followed by zero or more calls to serialize individual elements of
+// the compound type and one call to end the compound type.
+//
+// This impl is SerializeSeq so these methods are called after `serialize_seq`
+// is called on the Serializer.
+impl<'a> ser::SerializeSeq for &'a mut Serializer {
+    // Must match the `Ok` type of the serializer.
+    type Ok = ();
+    // Must match the `Error` type of the serializer.
+    type Error = Error;
+
+    // Serialize a single element of the sequence.
+    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    // Close the sequence.
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Same thing but for tuples.
+impl<'a> ser::SerializeTuple for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Same thing but for tuple structs.
+impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Tuple variants are a little different. Refer back to the
+// `serialize_tuple_variant` method above:
+//
+//    self.output += "{";
+//    variant.serialize(&mut *self)?;
+//    self.output += ":[";
+//
+// So the `end` method in this impl is responsible for closing both the `]` and
+// the `}`.
+impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Some `Serialize` types are not able to hold a key and value in memory at the
+// same time so `SerializeMap` implementations are required to support
+// `serialize_key` and `serialize_value` individually.
+//
+// There is a third optional method on the `SerializeMap` trait. The
+// `serialize_entry` method allows serializers to optimize for the case where
+// key and value are both available simultaneously. In JSON it doesn't make a
+// difference so the default behavior for `serialize_entry` is fine.
+impl<'a> ser::SerializeMap for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    // The Serde data model allows map keys to be any serializable type. JSON
+    // only allows string keys so the implementation below will produce invalid
+    // JSON if the key serializes as something other than a string.
+    //
+    // A real JSON serializer would need to validate that map keys are strings.
+    // This can be done by using a different Serializer to serialize the key
+    // (instead of `&mut **self`) and having that other serializer only
+    // implement `serialize_str` and return an error on any other data type.
+    fn serialize_key<T>(&mut self, _key: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!()
+    }
+
+    // It doesn't make a difference whether the colon is printed at the end of
+    // `serialize_key` or at the beginning of `serialize_value`. In this case
+    // the code is a bit simpler having it here.
+    fn serialize_value<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!()
+    }
+
+    fn end(self) -> Result<()> {
+        self.output.try_push(3).unwrap();
+        Ok(())
+    }
+}
+
+// Structs are like maps in which the keys are constrained to be compile-time
+// constant strings.
+impl<'a> ser::SerializeStruct for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        value.serialize(&mut **self)
+    }
+
+    fn end(self) -> Result<()> {
+        self.output.try_push(3).unwrap();
+        Ok(())
+    }
+}
+
+// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
+// closing both of the curly braces opened by `serialize_struct_variant`.
+impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[test]
+fn test_struct() {
+    use serde_derive::Serialize;
+
+    #[derive(Serialize)]
+    struct Test {
+        a: (),
+        b: bool,
+    }
+
+    let test = Test {
+        a: (),
+        b: false,
+    };
+
+    let mut expected = Vec::new();
+    expected.try_push(2).unwrap();
+    expected.try_push(0).unwrap();
+    expected.try_push(1).unwrap();
+    expected.try_push(0).unwrap();
+    expected.try_push(3).unwrap();
+    assert_eq!(to_vec(&test).unwrap(), expected);
+}
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
index 05ca21fbba06..a408f098fbfd 100644
--- a/samples/rust/Kconfig
+++ b/samples/rust/Kconfig
@@ -48,6 +48,14 @@ config SAMPLE_PUZZLEFS
 	  To compile this as a module, choose M here:
 	  the module will be called puzzlefs.
 
+config SAMPLE_RUST_SERDE
+	tristate "Serde"
+	help
+	  This option builds the Rust `serde` sample.
+
+	  To compile this as a module, choose M here:
+	  the module will be called rust_serde.
+
 	  If unsure, say N.
 
 config SAMPLE_RUST_HOSTPROGS
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index 364a38dbf90b..bc27f97d71ad 100644
--- a/samples/rust/Makefile
+++ b/samples/rust/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_SAMPLE_RUST_MINIMAL)		+= rust_minimal.o
 obj-$(CONFIG_SAMPLE_RUST_PRINT)			+= rust_print.o
 obj-$(CONFIG_SAMPLE_RUST_FS)			+= rust_fs.o
 obj-$(CONFIG_SAMPLE_PUZZLEFS)			+= puzzlefs.o
+obj-$(CONFIG_SAMPLE_RUST_SERDE)			+= rust_serde.o
 
 subdir-$(CONFIG_SAMPLE_RUST_HOSTPROGS)		+= hostprogs
diff --git a/samples/rust/local_data_format/de.rs b/samples/rust/local_data_format/de.rs
new file mode 100644
index 000000000000..32cfc53f98b3
--- /dev/null
+++ b/samples/rust/local_data_format/de.rs
@@ -0,0 +1,422 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+// Copyright 2018 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::error::{Error, Result};
+use serde::de::{self, Deserialize, DeserializeSeed, SeqAccess, Visitor};
+
+pub struct Deserializer<'de> {
+    // This string starts with the input data and characters are truncated off
+    // the beginning as data is parsed.
+    input: &'de [u8],
+}
+
+impl<'de> Deserializer<'de> {
+    // By convention, `Deserializer` constructors are named like `from_xyz`.
+    // That way basic use cases are satisfied by something like
+    // `serde_json::from_str(...)` while advanced use cases that require a
+    // deserializer can make one with `serde_json::Deserializer::from_str(...)`.
+    #[allow(clippy::should_implement_trait)]
+    pub fn from_bytes(input: &'de [u8]) -> Self {
+        Deserializer { input }
+    }
+}
+
+// By convention, the public API of a Serde deserializer is one or more
+// `from_xyz` methods such as `from_str`, `from_bytes`, or `from_reader`
+// depending on what Rust types the deserializer is able to consume as input.
+//
+// This basic deserializer supports only `from_str`.
+pub fn from_bytes<'a, T>(s: &'a [u8]) -> Result<T>
+where
+    T: Deserialize<'a>,
+{
+    let mut deserializer = Deserializer::from_bytes(s);
+    let t = T::deserialize(&mut deserializer)?;
+    if deserializer.input.is_empty() {
+        Ok(t)
+    } else {
+        Err(Error::TrailingCharacters)
+    }
+}
+
+// SERDE IS NOT A PARSING LIBRARY. This impl block defines a few basic parsing
+// functions from scratch. More complicated formats may wish to use a dedicated
+// parsing library to help implement their Serde deserializer.
+impl<'de> Deserializer<'de> {
+    // Look at the first character in the input without consuming it.
+    fn peek_byte(&mut self) -> Result<u8> {
+        self.input.iter().next().ok_or(Error::Eof).map(|v| *v)
+    }
+
+    // Consume the first character in the input.
+    fn next_byte(&mut self) -> Result<u8> {
+        let ch = self.peek_byte()?;
+        self.input = &self.input[1..];
+        Ok(ch)
+    }
+
+    // Parse the JSON identifier `true` or `false`.
+    fn parse_bool(&mut self) -> Result<bool> {
+        if self.input.starts_with(&[1]) {
+            self.input = &self.input[1..];
+            match self.next_byte()? {
+                42 => Ok(false),
+                43 => Ok(true),
+                _ => Err(Error::InvalidBooleanValue),
+            }
+        } else {
+            Err(Error::ExpectedBoolean)
+        }
+    }
+
+    // Parse a group of decimal digits as an unsigned integer of type T.
+    //
+    // This implementation is a bit too lenient, for example `001` is not
+    // allowed in JSON. Also the various arithmetic operations can overflow and
+    // panic or return bogus data. But it is good enough for example code!
+    fn parse_unsigned<T>(&mut self) -> Result<T> {
+        unimplemented!()
+    }
+
+    // Parse a possible minus sign followed by a group of decimal digits as a
+    // signed integer of type T.
+    fn parse_signed<T>(&mut self) -> Result<T> {
+        // Optional minus sign, delegate to `parse_unsigned`, negate if negative.
+        unimplemented!()
+    }
+}
+
+impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
+    type Error = Error;
+
+    // Look at the input data to decide what Serde data model type to
+    // deserialize as. Not all data formats are able to support this operation.
+    // Formats that support `deserialize_any` are known as self-describing.
+    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        match self.peek_byte()? {
+            0 => self.deserialize_unit(visitor),
+            1 => self.deserialize_bool(visitor),
+            2 => self.deserialize_map(visitor),
+            _ => Err(Error::Syntax),
+        }
+    }
+
+    // Uses the `parse_bool` parsing function defined above to read the JSON
+    // identifier `true` or `false` from the input.
+    //
+    // Parsing refers to looking at the input and deciding that it contains the
+    // JSON value `true` or `false`.
+    //
+    // Deserialization refers to mapping that JSON value into Serde's data
+    // model by invoking one of the `Visitor` methods. In the case of JSON and
+    // bool that mapping is straightforward so the distinction may seem silly,
+    // but in other cases Deserializers sometimes perform non-obvious mappings.
+    // For example the TOML format has a Datetime type and Serde's data model
+    // does not. In the `toml` crate, a Datetime in the input is deserialized by
+    // mapping it to a Serde data model "struct" type with a special name and a
+    // single field containing the Datetime represented as a string.
+    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_bool(self.parse_bool()?)
+    }
+
+    // The `parse_signed` function is generic over the integer type `T` so here
+    // it is invoked with `T=i8`. The next 8 methods are similar.
+    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i8(self.parse_signed()?)
+    }
+
+    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i16(self.parse_signed()?)
+    }
+
+    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i32(self.parse_signed()?)
+    }
+
+    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_i64(self.parse_signed()?)
+    }
+
+    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u8(self.parse_unsigned()?)
+    }
+
+    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u16(self.parse_unsigned()?)
+    }
+
+    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u32(self.parse_unsigned()?)
+    }
+
+    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_u64(self.parse_unsigned()?)
+    }
+
+    // The `Serializer` implementation on the previous page serialized chars as
+    // single-character strings so handle that representation here.
+    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // Refer to the "Understanding deserializer lifetimes" page for information
+    // about the three deserialization flavors of strings in Serde.
+    fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // The `Serializer` implementation on the previous page serialized byte
+    // arrays as JSON arrays of bytes. Handle that representation here.
+    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // An absent optional is represented as the JSON `null` and a present
+    // optional is represented as just the contained value.
+    //
+    // As commented in `Serializer` implementation, this is a lossy
+    // representation. For example the values `Some(())` and `None` both
+    // serialize as just `null`. Unfortunately this is typically what people
+    // expect when working with JSON. Other formats are encouraged to behave
+    // more intelligently if possible.
+    fn deserialize_option<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // In Serde, unit means an anonymous value containing no data.
+    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        if self.input.starts_with(&[0]) {
+            self.input = &self.input[1..];
+            visitor.visit_unit()
+        } else {
+            Err(Error::ExpectedNull)
+        }
+    }
+
+    // Unit struct means a named value containing no data.
+    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_unit(visitor)
+    }
+
+    // As is done here, serializers are encouraged to treat newtype structs as
+    // insignificant wrappers around the data they contain. That means not
+    // parsing anything other than the contained value.
+    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_newtype_struct(self)
+    }
+
+    // Deserialization of compound types like sequences and maps happens by
+    // passing the visitor an "Access" object that gives it the ability to
+    // iterate through the data contained in the sequence.
+    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // Tuples look just like sequences in JSON. Some formats may be able to
+    // represent tuples more efficiently.
+    //
+    // As indicated by the length parameter, the `Deserialize` implementation
+    // for a tuple in the Serde data model is required to know the length of the
+    // tuple before even looking at the input data.
+    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_seq(visitor)
+    }
+
+    // Tuple structs look just like sequences in JSON.
+    fn deserialize_tuple_struct<V>(
+        self,
+        _name: &'static str,
+        _len: usize,
+        visitor: V,
+    ) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_seq(visitor)
+    }
+
+    // Much like `deserialize_seq` but calls the visitors `visit_map` method
+    // with a `MapAccess` implementation, rather than the visitor's `visit_seq`
+    // method with a `SeqAccess` implementation.
+    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        // Parse the opening brace of the map.
+        if self.next_byte()? == 2 {
+            // Give the visitor access to each entry of the map.
+            let value = visitor.visit_seq(StructFieldsVisitor::new(self))?;
+            // Parse the closing brace of the map.
+            if self.next_byte()? == 3 {
+                Ok(value)
+            } else {
+                Err(Error::ExpectedMapEnd)
+            }
+        } else {
+            Err(Error::ExpectedMap)
+        }
+    }
+
+    // Structs look just like maps in JSON.
+    //
+    // Notice the `fields` parameter - a "struct" in the Serde data model means
+    // that the `Deserialize` implementation is required to know what the fields
+    // are before even looking at the input data. Any key-value pairing in which
+    // the fields cannot be known ahead of time is probably a map.
+    fn deserialize_struct<V>(
+        self,
+        _name: &'static str,
+        _fields: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_map(visitor)
+    }
+
+    fn deserialize_enum<V>(
+        self,
+        _name: &'static str,
+        _variants: &'static [&'static str],
+        _visitor: V,
+    ) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        unimplemented!()
+    }
+
+    // An identifier in Serde is the type that identifies a field of a struct or
+    // the variant of an enum. In JSON, struct fields and enum variants are
+    // represented as strings. In other formats they may be represented as
+    // numeric indices.
+    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_str(visitor)
+    }
+
+    // Like `deserialize_any` but indicates to the `Deserializer` that it makes
+    // no difference which `Visitor` method is called because the data is
+    // ignored.
+    //
+    // Some deserializers are able to implement this more efficiently than
+    // `deserialize_any`, for example by rapidly skipping over matched
+    // delimiters without paying close attention to the data in between.
+    //
+    // Some formats are not able to implement this at all. Formats that can
+    // implement `deserialize_any` and `deserialize_ignored_any` are known as
+    // self-describing.
+    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_any(visitor)
+    }
+}
+
+struct StructFieldsVisitor<'a, 'de> {
+    de: &'a mut Deserializer<'de>,
+}
+
+impl<'a, 'de> StructFieldsVisitor<'a, 'de> {
+    fn new(de: &'a mut Deserializer<'de>) -> Self {
+        StructFieldsVisitor { de }
+    }
+}
+
+impl<'de, 'a> SeqAccess<'de> for StructFieldsVisitor<'a, 'de> {
+    type Error = Error;
+
+    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+    where
+        T: DeserializeSeed<'de>,
+    {
+        // Check if there are no more elements.
+        if self.de.peek_byte()? == 3 {
+            return Ok(None);
+        }
+        // Deserialize an array element.
+        seed.deserialize(&mut *self.de).map(Some)
+    }
+}
diff --git a/samples/rust/local_data_format/error.rs b/samples/rust/local_data_format/error.rs
new file mode 100644
index 000000000000..8d913580f713
--- /dev/null
+++ b/samples/rust/local_data_format/error.rs
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+// Copyright 2018 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::fmt::{self, Display};
+use serde::{de, ser};
+
+pub type Result<T> = kernel::error::Result<T, Error>;
+
+// This is a bare-bones implementation. A real library would provide additional
+// information in its error type, for example the line and column at which the
+// error occurred, the byte offset into the input, or the current key being
+// processed.
+#[derive(Debug)]
+pub enum Error {
+    // One or more variants that can be created by data structures through the
+    // `ser::Error` and `de::Error` traits. For example the Serialize impl for
+    // Mutex<T> might return an error because the mutex is poisoned, or the
+    // Deserialize impl for a struct may return an error because a required
+    // field is missing.
+    Message,
+
+    // Zero or more variants that can be created directly by the Serializer and
+    // Deserializer without going through `ser::Error` and `de::Error`. These
+    // are specific to the format, in this case JSON.
+    Eof,
+    Syntax,
+    ExpectedBoolean,
+    InvalidBooleanValue,
+    ExpectedInteger,
+    ExpectedString,
+    ExpectedNull,
+    ExpectedArray,
+    ExpectedArrayComma,
+    ExpectedArrayEnd,
+    ExpectedMap,
+    ExpectedMapColon,
+    ExpectedMapComma,
+    ExpectedMapEnd,
+    ExpectedEnum,
+    TrailingCharacters,
+}
+
+impl ser::Error for Error {
+    fn custom<T: Display>(_msg: T) -> Self {
+        Error::Message
+    }
+}
+
+impl de::Error for Error {
+    fn custom<T: Display>(_msg: T) -> Self {
+        Error::Message
+    }
+}
+
+impl Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Error::Message => write!(f, "message"),
+            Error::Eof => f.write_str("unexpected end of input"),
+            /* and so forth */
+            _ => unimplemented!(),
+        }
+    }
+}
+
+//impl core::error::Error for Error {}
diff --git a/samples/rust/local_data_format/ser.rs b/samples/rust/local_data_format/ser.rs
new file mode 100644
index 000000000000..f4f17eb6da66
--- /dev/null
+++ b/samples/rust/local_data_format/ser.rs
@@ -0,0 +1,443 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+// Copyright 2018 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::error::{Error, Result};
+use alloc::vec::Vec;
+use serde::ser::{self, Serialize};
+
+pub struct Serializer {
+    // This string starts empty and JSON is appended as values are serialized.
+    output: Vec<u8>,
+}
+
+// By convention, the public API of a Serde serializer is one or more `to_abc`
+// functions such as `to_string`, `to_bytes`, or `to_writer` depending on what
+// Rust types the serializer is able to produce as output.
+//
+// This basic serializer supports only `to_string`.
+pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
+where
+    T: Serialize,
+{
+    let mut serializer = Serializer { output: Vec::new() };
+    value.serialize(&mut serializer)?;
+    Ok(serializer.output)
+}
+
+impl<'a> ser::Serializer for &'a mut Serializer {
+    // The output type produced by this `Serializer` during successful
+    // serialization. Most serializers that produce text or binary output should
+    // set `Ok = ()` and serialize into an `io::Write` or buffer contained
+    // within the `Serializer` instance, as happens here. Serializers that build
+    // in-memory data structures may be simplified by using `Ok` to propagate
+    // the data structure around.
+    type Ok = ();
+
+    // The error type when some error occurs during serialization.
+    type Error = Error;
+
+    // Associated types for keeping track of additional state while serializing
+    // compound data structures like sequences and maps. In this case no
+    // additional state is required beyond what is already stored in the
+    // Serializer struct.
+    type SerializeSeq = Self;
+    type SerializeTuple = Self;
+    type SerializeTupleStruct = Self;
+    type SerializeTupleVariant = Self;
+    type SerializeMap = Self;
+    type SerializeStruct = Self;
+    type SerializeStructVariant = Self;
+
+    // Here we go with the simple methods. The following 12 methods receive one
+    // of the primitive types of the data model and map it to JSON by appending
+    // into the output string.
+    fn serialize_bool(self, v: bool) -> Result<()> {
+        self.output.try_push(1).unwrap();
+        self.output.try_push(if v { 43 } else { 42 }).unwrap();
+        Ok(())
+    }
+
+    // JSON does not distinguish between different sizes of integers, so all
+    // signed integers will be serialized the same and all unsigned integers
+    // will be serialized the same. Other formats, especially compact binary
+    // formats, may need independent logic for the different sizes.
+    fn serialize_i8(self, v: i8) -> Result<()> {
+        self.serialize_i64(i64::from(v))
+    }
+
+    fn serialize_i16(self, v: i16) -> Result<()> {
+        self.serialize_i64(i64::from(v))
+    }
+
+    fn serialize_i32(self, v: i32) -> Result<()> {
+        self.serialize_i64(i64::from(v))
+    }
+
+    // Not particularly efficient but this is example code anyway. A more
+    // performant approach would be to use the `itoa` crate.
+    fn serialize_i64(self, _v: i64) -> Result<()> {
+        unimplemented!();
+    }
+
+    fn serialize_u8(self, v: u8) -> Result<()> {
+        self.serialize_u64(u64::from(v))
+    }
+
+    fn serialize_u16(self, v: u16) -> Result<()> {
+        self.serialize_u64(u64::from(v))
+    }
+
+    fn serialize_u32(self, v: u32) -> Result<()> {
+        self.serialize_u64(u64::from(v))
+    }
+
+    fn serialize_u64(self, _v: u64) -> Result<()> {
+        unimplemented!();
+    }
+
+    // Serialize a char as a single-character string. Other formats may
+    // represent this differently.
+    fn serialize_char(self, _v: char) -> Result<()> {
+        unimplemented!();
+    }
+
+    // This only works for strings that don't require escape sequences but you
+    // get the idea. For example it would emit invalid JSON if the input string
+    // contains a '"' character.
+    fn serialize_str(self, _v: &str) -> Result<()> {
+        unimplemented!();
+    }
+
+    // Serialize a byte array as an array of bytes. Could also use a base64
+    // string here. Binary formats will typically represent byte arrays more
+    // compactly.
+    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
+        use serde::ser::SerializeSeq;
+        let mut seq = self.serialize_seq(Some(v.len()))?;
+        for byte in v {
+            seq.serialize_element(byte)?;
+        }
+        seq.end()
+    }
+
+    // An absent optional is represented as the JSON `null`.
+    fn serialize_none(self) -> Result<()> {
+        self.serialize_unit()
+    }
+
+    // A present optional is represented as just the contained value. Note that
+    // this is a lossy representation. For example the values `Some(())` and
+    // `None` both serialize as just `null`. Unfortunately this is typically
+    // what people expect when working with JSON. Other formats are encouraged
+    // to behave more intelligently if possible.
+    fn serialize_some<T>(self, value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        value.serialize(self)
+    }
+
+    // In Serde, unit means an anonymous value containing no data. Map this to
+    // JSON as `null`.
+    fn serialize_unit(self) -> Result<()> {
+        self.output.try_push(0).unwrap();
+        Ok(())
+    }
+
+    // Unit struct means a named value containing no data. Again, since there is
+    // no data, map this to JSON as `null`. There is no need to serialize the
+    // name in most formats.
+    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+        self.serialize_unit()
+    }
+
+    // When serializing a unit variant (or any other kind of variant), formats
+    // can choose whether to keep track of it by index or by name. Binary
+    // formats typically use the index of the variant and human-readable formats
+    // typically use the name.
+    fn serialize_unit_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        variant: &'static str,
+    ) -> Result<()> {
+        self.serialize_str(variant)
+    }
+
+    // As is done here, serializers are encouraged to treat newtype structs as
+    // insignificant wrappers around the data they contain.
+    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        value.serialize(self)
+    }
+
+    // Note that newtype variant (and all of the other variant serialization
+    // methods) refer exclusively to the "externally tagged" enum
+    // representation.
+    //
+    // Serialize this to JSON in externally tagged form as `{ NAME: VALUE }`.
+    fn serialize_newtype_variant<T>(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _value: &T,
+    ) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    // Now we get to the serialization of compound types.
+    //
+    // The start of the sequence, each value, and the end are three separate
+    // method calls. This one is responsible only for serializing the start,
+    // which in JSON is `[`.
+    //
+    // The length of the sequence may or may not be known ahead of time. This
+    // doesn't make a difference in JSON because the length is not represented
+    // explicitly in the serialized form. Some serializers may only be able to
+    // support sequences for which the length is known up front.
+    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+        unimplemented!();
+    }
+
+    // Tuples look just like sequences in JSON. Some formats may be able to
+    // represent tuples more efficiently by omitting the length, since tuple
+    // means that the corresponding `Deserialize implementation will know the
+    // length without needing to look at the serialized data.
+    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+        self.serialize_seq(Some(len))
+    }
+
+    // Tuple structs look just like sequences in JSON.
+    fn serialize_tuple_struct(
+        self,
+        _name: &'static str,
+        len: usize,
+    ) -> Result<Self::SerializeTupleStruct> {
+        self.serialize_seq(Some(len))
+    }
+
+    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }`. Again
+    // this method is only responsible for the externally tagged representation.
+    fn serialize_tuple_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleVariant> {
+        unimplemented!();
+    }
+
+    // Maps are represented in JSON as `{ K: V, K: V, ... }`.
+    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+        self.output.try_push(2).unwrap();
+        Ok(self)
+    }
+
+    // Structs look just like maps in JSON. In particular, JSON requires that we
+    // serialize the field names of the struct. Other formats may be able to
+    // omit the field names when serializing structs because the corresponding
+    // Deserialize implementation is required to know what the keys are without
+    // looking at the serialized data.
+    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+        self.serialize_map(Some(len))
+    }
+
+    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }`.
+    // This is the externally tagged representation.
+    fn serialize_struct_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeStructVariant> {
+        unimplemented!();
+    }
+
+    fn collect_str<T: ?Sized>(self, _: &T) -> Result<()>
+    where
+        T: core::fmt::Display,
+    {
+        unimplemented!()
+    }
+}
+
+// The following 7 impls deal with the serialization of compound types like
+// sequences and maps. Serialization of such types is begun by a Serializer
+// method and followed by zero or more calls to serialize individual elements of
+// the compound type and one call to end the compound type.
+//
+// This impl is SerializeSeq so these methods are called after `serialize_seq`
+// is called on the Serializer.
+impl<'a> ser::SerializeSeq for &'a mut Serializer {
+    // Must match the `Ok` type of the serializer.
+    type Ok = ();
+    // Must match the `Error` type of the serializer.
+    type Error = Error;
+
+    // Serialize a single element of the sequence.
+    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    // Close the sequence.
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Same thing but for tuples.
+impl<'a> ser::SerializeTuple for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Same thing but for tuple structs.
+impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Tuple variants are a little different. Refer back to the
+// `serialize_tuple_variant` method above:
+//
+//    self.output += "{";
+//    variant.serialize(&mut *self)?;
+//    self.output += ":[";
+//
+// So the `end` method in this impl is responsible for closing both the `]` and
+// the `}`.
+impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
+
+// Some `Serialize` types are not able to hold a key and value in memory at the
+// same time so `SerializeMap` implementations are required to support
+// `serialize_key` and `serialize_value` individually.
+//
+// There is a third optional method on the `SerializeMap` trait. The
+// `serialize_entry` method allows serializers to optimize for the case where
+// key and value are both available simultaneously. In JSON it doesn't make a
+// difference so the default behavior for `serialize_entry` is fine.
+impl<'a> ser::SerializeMap for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    // The Serde data model allows map keys to be any serializable type. JSON
+    // only allows string keys so the implementation below will produce invalid
+    // JSON if the key serializes as something other than a string.
+    //
+    // A real JSON serializer would need to validate that map keys are strings.
+    // This can be done by using a different Serializer to serialize the key
+    // (instead of `&mut **self`) and having that other serializer only
+    // implement `serialize_str` and return an error on any other data type.
+    fn serialize_key<T>(&mut self, _key: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!()
+    }
+
+    // It doesn't make a difference whether the colon is printed at the end of
+    // `serialize_key` or at the beginning of `serialize_value`. In this case
+    // the code is a bit simpler having it here.
+    fn serialize_value<T>(&mut self, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!()
+    }
+
+    fn end(self) -> Result<()> {
+        self.output.try_push(3).unwrap();
+        Ok(())
+    }
+}
+
+// Structs are like maps in which the keys are constrained to be compile-time
+// constant strings.
+impl<'a> ser::SerializeStruct for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        value.serialize(&mut **self)
+    }
+
+    fn end(self) -> Result<()> {
+        self.output.try_push(3).unwrap();
+        Ok(())
+    }
+}
+
+// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
+// closing both of the curly braces opened by `serialize_struct_variant`.
+impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
+    type Ok = ();
+    type Error = Error;
+
+    fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
+    where
+        T: ?Sized + Serialize,
+    {
+        unimplemented!();
+    }
+
+    fn end(self) -> Result<()> {
+        unimplemented!();
+    }
+}
diff --git a/samples/rust/rust_serde.rs b/samples/rust/rust_serde.rs
new file mode 100644
index 000000000000..3d4957dd0822
--- /dev/null
+++ b/samples/rust/rust_serde.rs
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust `serde` sample.
+//!
+//! It uses a data format from the `kernel` crate, as well as defining
+//! one here ("local"). Then it uses both on a type that uses `serve_derive`.
+
+use kernel::prelude::*;
+use serde_derive::{Deserialize, Serialize};
+
+module! {
+    type: RustSerde,
+    name: "rust_serde",
+    author: "Rust for Linux Contributors",
+    description: "Rust `serde` sample",
+    license: "GPL",
+}
+
+struct RustSerde;
+
+pub mod local_data_format {
+    #![allow(missing_docs)]
+
+    mod de;
+    mod error;
+    mod ser;
+
+    pub use de::{from_bytes, Deserializer};
+    pub use error::{Error, Result};
+    pub use ser::{to_vec, Serializer};
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+struct S {
+    a: (),
+    b: bool,
+    c: bool,
+    d: (),
+}
+
+impl kernel::Module for RustSerde {
+    fn init(_module: &'static ThisModule) -> Result<Self> {
+        pr_info!("Rust serde sample (init)\n");
+
+        let original = S {
+            a: (),
+            b: false,
+            c: true,
+            d: (),
+        };
+        crate::pr_info!("            original = {:?}", original);
+
+        let serialized = kernel::test_serde::to_vec(&original).unwrap();
+        crate::pr_info!("          serialized = {:?}", serialized);
+
+        let deserialized: S = kernel::test_serde::from_bytes(&serialized).unwrap();
+        crate::pr_info!("        deserialized = {:?}", deserialized);
+
+        let serialized = local_data_format::to_vec(&deserialized).unwrap();
+        crate::pr_info!("  serialized (local) = {:?}", serialized);
+
+        let deserialized: S = local_data_format::from_bytes(&serialized).unwrap();
+        crate::pr_info!("deserialized (local) = {:?}", deserialized);
+
+        Ok(RustSerde)
+    }
+}
+
+impl Drop for RustSerde {
+    fn drop(&mut self) {
+        pr_info!("Rust serde sample (exit)\n");
+    }
+}
-- 
2.40.1


  parent reply	other threads:[~2023-06-09  6:54 UTC|newest]

Thread overview: 135+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-09  6:29 [RFC PATCH 00/80] Rust PuzzleFS filesystem driver Ariel Miculas
2023-06-09  6:29 ` [PATCH 01/80] rust: add definitions for ref-counted inodes and dentries Ariel Miculas
2023-06-09  6:30 ` [PATCH 02/80] rust: add ability to register a file system Ariel Miculas
2023-06-09  9:23   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 03/80] rust: define fs context Ariel Miculas
2023-06-09  6:30 ` [PATCH 04/80] rust: add support for file system parameters Ariel Miculas
2023-06-09  6:30 ` [PATCH 05/80] rust: kernel: add libraries required by the filesystem abstractions Ariel Miculas
2023-06-09  9:46   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 06/80] rust: allow fs driver to initialise new superblocks Ariel Miculas
2023-06-09  6:30 ` [PATCH 07/80] rust: add `module_fs` macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 08/80] WIP: rust: allow fs to be populated Ariel Miculas
2023-06-09  6:30 ` [PATCH 09/80] rust: kernel: backport the delay module from the rust branch Ariel Miculas
2023-06-09  9:29   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 10/80] rust: kernel: add container_of macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 11/80] rust: kernel: add offset_of macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 12/80] drop: Add crate::pr_warn declaration Ariel Miculas
2023-06-09  9:29   ` Miguel Ojeda
2023-06-09 10:46     ` Ariel Miculas (amiculas)
2023-06-09  6:30 ` [PATCH 13/80] rust: kernel: rename from_kernel_errno to from_errno Ariel Miculas
2023-06-09  9:56   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 14/80] rust: kernel: Rename from_pointer to from_foreing and into_pointer to into_foreign Ariel Miculas
2023-06-09  9:57   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 15/80] rust: kernel: add count_paren_items macro, needed by define_fs_params macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 16/80] rust: helpers: add missing rust helper 'alloc_pages' Ariel Miculas
2023-06-09  9:57   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 17/80] kernel: configs: add qemu-busybox-min.config Ariel Miculas
2023-06-09  9:39   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 18/80] rust: kernel: format the rust code Ariel Miculas
2023-06-09  9:21   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 19/80] samples: puzzlefs: add initial puzzlefs sample, copied from rust_fs.rs Ariel Miculas
2023-06-09  6:30 ` [PATCH 20/80] kernel: configs: enable rust samples in rust.config Ariel Miculas
2023-06-09  9:25   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 22/80] rust: proc-macro2: add SPDX License Identifiers Ariel Miculas
2023-06-09  6:30 ` [PATCH 23/80] rust: proc-macro2: remove `unicode_ident` dependency Ariel Miculas
2023-06-09  6:30 ` [PATCH 24/80] rust: quote: import crate Ariel Miculas
2023-06-09  6:30 ` [PATCH 25/80] rust: quote: add SPDX License Identifiers Ariel Miculas
2023-06-09  6:30 ` [PATCH 27/80] rust: syn: " Ariel Miculas
2023-06-09  6:30 ` [PATCH 28/80] rust: syn: remove `unicode-ident` dependency Ariel Miculas
2023-06-09  6:30 ` [PATCH 30/80] rust: serde: add `no_fp_fmt_parse` support Ariel Miculas
2023-06-09  6:30 ` [PATCH 31/80] rust: serde: add SPDX License Identifiers Ariel Miculas
2023-06-10  0:19   ` Kent Overstreet
2023-06-10  6:43     ` Greg KH
2023-06-10 13:18       ` Kent Overstreet
2023-06-10 15:28         ` Greg KH
2023-06-10  0:25   ` Kent Overstreet
2023-06-10  9:04     ` Andreas Hindborg (Samsung)
2023-06-10 13:20       ` Kent Overstreet
2023-06-12  8:56         ` Ariel Miculas
2023-06-10  9:33     ` Miguel Ojeda
2023-06-12 11:58     ` Ariel Miculas
2023-06-15 15:05     ` Ariel Miculas
2023-06-17 16:04       ` Kent Overstreet
2023-06-09  6:30 ` [PATCH 33/80] rust: serde_derive: " Ariel Miculas
2023-06-09  6:30 ` [PATCH 34/80] rust: Kbuild: enable `proc-macro2`, `quote`, `syn`, `serde` and `serde_derive` Ariel Miculas
2023-06-09  6:30 ` Ariel Miculas [this message]
2023-06-09  6:30 ` [PATCH 36/80] Add SAMPLE_RUST_SERDE in rust.config Ariel Miculas
2023-06-09  6:30 ` [PATCH 37/80] rust: kernel: fix compile errors after rebase to rust-next Ariel Miculas
2023-06-09  9:38   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 39/80] rust: serde_cbor: add SPDX License Identifiers Ariel Miculas
2023-06-09  6:30 ` [PATCH 40/80] rust: serde_cbor: add no_fp_fmt_parse support Ariel Miculas
2023-06-09  6:30 ` [PATCH 41/80] rust: Kbuild: enable serde_cbor Ariel Miculas
2023-06-09 10:21   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 42/80] samples: rust: add cbor serialize/deserialize example Ariel Miculas
2023-06-09  6:30 ` [PATCH 43/80] rust: serde_cbor: add support for serde_cbor's from_slice method by using a custom alloc_kernel feature Ariel Miculas
2023-06-09  9:55   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 44/80] rust: serde: add support for deserializing Vec with kernel_alloc feature Ariel Miculas
2023-06-09 10:10   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 45/80] rust: file: Replace UnsafeCell with Opaque for File Ariel Miculas
2023-06-09  6:30 ` [PATCH 46/80] rust: kernel: implement fmt::Debug for CString Ariel Miculas
2023-06-09  6:30 ` [PATCH 47/80] samples: puzzlefs: rename RustFs to PuzzleFs Ariel Miculas
2023-06-09  6:30 ` [PATCH 48/80] samples: puzzlefs: add basic deserializing support for the puzzlefs metadata Ariel Miculas
2023-06-09  6:30 ` [PATCH 49/80] rust: file: present the filesystem context to the open function Ariel Miculas
2023-06-09  6:30 ` [PATCH 50/80] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount Ariel Miculas
2023-06-09  6:30 ` [PATCH 51/80] rust: file: add from_path, from_path_in_root_mnt and read_with_offset methods to File Ariel Miculas
2023-06-09  6:30 ` [PATCH 52/80] samples: puzzlefs: pass the Vfsmount structure from open to read and return the contents of the data file inside /home/puzzlefs_oci Ariel Miculas
2023-06-09  6:30 ` [PATCH 53/80] rust: file: move from_path, from_path_in_root_mnt and read_with_offset methods to a RegularFile newtype Ariel Miculas
2023-06-09  6:30 ` [PATCH 54/80] rust: file: ensure RegularFile can only create regular files Ariel Miculas
2023-06-09  6:30 ` [PATCH 55/80] rust: file: add get_pos method to RegularFile Ariel Miculas
2023-06-09  6:30 ` [PATCH 56/80] rust: file: add methods read_to_end, get_file_size and update_pos " Ariel Miculas
2023-06-09  6:30 ` [PATCH 57/80] rust: file: define a minimal Read trait and implement it for RegularFile Ariel Miculas
2023-06-09  6:30 ` [PATCH 58/80] samples: puzzlefs: add cbor_get_array_size method Ariel Miculas
2023-06-09  6:30 ` [PATCH 59/80] samples: puzzlefs: add KernelError to WireFormatError and implement From conversion Ariel Miculas
2023-06-09  6:30 ` [PATCH 60/80] samples: puzzlefs: implement new for MetadataBlob Ariel Miculas
2023-06-09  6:30 ` [PATCH 61/80] samples: puzzlefs: build puzzlefs into the kernel, thus avoiding the need to export rust symbols Ariel Miculas
2023-06-09  6:31 ` [PATCH 62/80] rust: alloc: add try_clone for Vec<T> Ariel Miculas
2023-06-09  6:31 ` [PATCH 63/80] rust: alloc: add from_iter_fallible " Ariel Miculas
2023-06-09 10:06   ` Miguel Ojeda
2023-06-09  6:31 ` [PATCH 64/80] samples: puzzlefs: implement to_errno and from_errno for WireFormatError Ariel Miculas
2023-06-09  6:31 ` [PATCH 65/80] samples: puzzlefs: add TryReserveError (and from conversion) to WireFormatError Ariel Miculas
2023-06-09  6:31 ` [PATCH 66/80] samples: puzzlefs: add higher level inode related functionality Ariel Miculas
2023-06-09  6:31 ` [PATCH 67/80] samples: puzzlefs: populate the directory entries with the inodes from the puzzlefs metadata file Ariel Miculas
2023-06-09  6:31 ` [PATCH 68/80] rust: hex: import crate Ariel Miculas
2023-06-09  6:31 ` [PATCH 69/80] rust: hex: add SPDX license identifiers Ariel Miculas
2023-06-09  6:31 ` [PATCH 70/80] rust: Kbuild: enable `hex` Ariel Miculas
2023-06-09  6:31 ` [PATCH 71/80] rust: hex: implement FromHex trait and hex::decode using a custom kernel_alloc feature Ariel Miculas
2023-06-09  6:31 ` [PATCH 72/80] rust: hex: add encode_hex_iter and encode_hex_upper_iter methods Ariel Miculas
2023-06-09  6:31 ` [PATCH 73/80] rust: puzzlefs: add HexError to WireFormatError and implement the From conversion Ariel Miculas
2023-06-09  6:31 ` [PATCH 74/80] rust: puzzlefs: display the error value for WireFormatError::KernelError Ariel Miculas
2023-06-09  6:31 ` [PATCH 75/80] samples: puzzlefs: add Rootfs and Digest structs to types.rs Ariel Miculas
2023-06-09  6:31 ` [PATCH 76/80] samples: puzzlefs: implement the conversion from WireFormatError to kernel::error::Error Ariel Miculas
2023-06-09  6:31 ` [PATCH 77/80] rust: puzzlefs: read the puzzlefs image manifest instead of an individual metadata layer Ariel Miculas
2023-06-09  6:31 ` [PATCH 78/80] rust: puzzlefs: rename PuzzleFs to PuzzleFsModule to avoid confusion with the PuzzleFS struct Ariel Miculas
2023-06-09  6:31 ` [PATCH 79/80] rust: puzzlefs: add support for reading files Ariel Miculas
2023-06-09  6:31 ` [PATCH 80/80] rust: puzzlefs: add oci_root_dir and image_manifest filesystem parameters Ariel Miculas
2023-06-09 10:26 ` [RFC PATCH 00/80] Rust PuzzleFS filesystem driver Miguel Ojeda
2023-06-09 10:36 ` Christian Brauner
2023-06-09 11:22   ` Ariel Miculas (amiculas)
2023-06-09 11:45     ` Christian Brauner
2023-06-09 12:03       ` Ariel Miculas (amiculas)
2023-06-09 12:56         ` Gao Xiang
2023-06-09 12:07       ` Miguel Ojeda
2023-06-09 12:11         ` Ariel Miculas (amiculas)
2023-06-09 12:21           ` Greg KH
2023-06-09 13:05         ` Alice Ryhl
2023-06-09 12:20       ` Colin Walters
2023-06-09 12:42         ` Christian Brauner
2023-06-09 17:28           ` Serge Hallyn
2023-06-09 13:45         ` Ariel Miculas (amiculas)
2023-06-09 17:10           ` Trilok Soni
2023-06-09 17:16             ` Ariel Miculas (amiculas)
2023-06-09 17:41               ` Miguel Ojeda
2023-06-09 18:49                 ` James Bottomley
2023-06-09 19:08                   ` Miguel Ojeda
2023-06-09 19:11                   ` Ariel Miculas
2023-06-09 20:01                     ` James Bottomley
2023-06-10  9:34                     ` Miguel Ojeda
2023-06-09 18:43               ` James Bottomley
2023-06-09 18:59                 ` Ariel Miculas (amiculas)
2023-06-09 19:20                   ` Ariel Miculas
2023-06-09 19:45                     ` Trilok Soni
2023-06-09 19:53                   ` Alice Ryhl
2023-06-09 11:42   ` Miguel Ojeda
2023-06-09 23:52   ` Kent Overstreet
2023-06-10  9:40     ` Miguel Ojeda
2023-06-10  0:09 ` Kent Overstreet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230609063118.24852-36-amiculas@cisco.com \
    --to=amiculas@cisco.com \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.