Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wishlist: Blocked on upstream changes #564

Open
jonasbb opened this issue Mar 4, 2023 · 0 comments
Open

Wishlist: Blocked on upstream changes #564

jonasbb opened this issue Mar 4, 2023 · 0 comments
Labels
enhancement New feature or request

Comments

@jonasbb
Copy link
Owner

jonasbb commented Mar 4, 2023

  • MSRV Rust 1.64:
    • Use workspace.package and workspace.dependencies. The main advantage is sharing the metadata between the related packages. The slightly simpler dependency management is a bonus.
  • feature(adt_const_params)
    • Add extra layers for serializing/deserializing. Serialize struct with additional root element #340 (comment)

       #![feature(adt_const_params)]
       
       #[derive(Copy, Clone, Debug, Default)]
       pub struct Layer<const FIELD: &'static str, T: ?Sized>(T);
       
       impl<const FIELD: &'static str, T, U> SerializeAs<T> for Layer<FIELD, U>
       where
           U: SerializeAs<T>,
           T: ?Sized,
           U: ?Sized,
       {
           fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
               use serde::ser::SerializeStruct;
       
               let mut ser_struct = serializer.serialize_struct("Layer", 1)?;
               ser_struct.serialize_field(FIELD, &ser::SerializeAsWrap::<T, U>::new(source))?;
               ser_struct.end()
           }
       }
       
       // Can be used like this
       #[serde_as]
       #[derive(Serialize)]
       struct Data {
           i: i32,
           #[serde_as(as = r#"Layer<"extra", Layer<"foobar", Layer<"really_another_one", DisplayFromStr>>>"#)]
           b: bool,
       }
       
       // or like
       serde_json::to_string(&Layer::<"root">(&data))

      https://github.com/dtolnay/monostate contains a solution to encode &str into a static type without requiring adt_const_params. It doesn't quite fit the above use case, since the value is not accessible as a &'static str. But Layer could be implemented if it uses serialize_map.

    • Add a macro-free version of with_prefix!.

    • Get rid of the special key name requirement for `KeyValueMap

      // TODO Replace this with a const generic string once adt_const_params is stable.
      // This will allow something like this.
      // The `"id"` part is the field name, which gets converted to/from the map key.
      // #[serde_as(as = r#"KeyValueMap<"id", _>"#)]
      // Vec<SimpleStruct>,
      static MAP_KEY_IDENTIFIER: &str = "$key$";

  • feature(array_try_from_fn) Tracking issue for array_from_fn and try_array_from_fn rust-lang/rust#89379
    • Replace the unsafe implementation of array_from_iterator with something from std.
      Provide a means of turning iterators into fixed-size arrays rust-lang/rust#81615
      /// Collect an array of a fixed size from an iterator.
      ///
      /// # Safety
      /// The code follow exactly the pattern of initializing an array element-by-element from the standard library.
      /// <https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-element>
      pub(crate) fn array_from_iterator<I, T, E, const N: usize>(
      mut iter: I,
      expected: &dyn Expected,
      ) -> Result<[T; N], E>
      where
      I: Iterator<Item = Result<T, E>>,
      E: DeError,
      {
      use core::mem::MaybeUninit;
      fn drop_array_elems<T, const N: usize>(num: usize, mut arr: [MaybeUninit<T>; N]) {
      arr[..num].iter_mut().for_each(|elem| {
      // TODO This would be better with assume_init_drop nightly function
      // https://github.com/rust-lang/rust/issues/63567
      unsafe { core::ptr::drop_in_place(elem.as_mut_ptr()) };
      });
      }
      // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
      // safe because the type we are claiming to have initialized here is a
      // bunch of `MaybeUninit`s, which do not require initialization.
      //
      // TODO could be simplified with nightly maybe_uninit_uninit_array feature
      // https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.uninit_array
      let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
      // Dropping a `MaybeUninit` does nothing. Thus using raw pointer
      // assignment instead of `ptr::write` does not cause the old
      // uninitialized value to be dropped. Also if there is a panic during
      // this loop, we have a memory leak, but there is no memory safety
      // issue.
      for (idx, elem) in arr[..].iter_mut().enumerate() {
      *elem = match iter.next() {
      Some(Ok(value)) => MaybeUninit::new(value),
      Some(Err(err)) => {
      drop_array_elems(idx, arr);
      return Err(err);
      }
      None => {
      drop_array_elems(idx, arr);
      return Err(DeError::invalid_length(idx, expected));
      }
      };
      }
      // Everything is initialized. Transmute the array to the
      // initialized type.
      // A normal transmute is not possible because of:
      // https://github.com/rust-lang/rust/issues/61956
      Ok(unsafe { core::mem::transmute_copy::<_, [T; N]>(&arr) })
      }
  • Use workspace lints with separate overrides per crate: Packages overriding inherited lints in Cargo.toml + adding lints rust-lang/cargo#13157
@jonasbb jonasbb added the enhancement New feature or request label Mar 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant