Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:

- name: check-features
run: |
cargo check --no-default-features --features bit-vec
cargo check --no-default-features --features serde
cargo check --no-default-features --features serde,decode

Expand All @@ -50,7 +51,7 @@ jobs:

- name: test
run: |
cargo test --all
cargo test --all --all-features

- name: test no-std
run: |
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ categories = ["no-std", "encoding"]
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"]

[dependencies]
bitvec = { version = "0.20.1", default-features = false, features = ["alloc"], optional = true }
cfg-if = "1.0"
scale-info-derive = { version = "0.4.0", path = "derive", default-features = false, optional = true }
serde = { version = "1", default-features = false, optional = true, features = ["derive", "alloc"] }
Expand All @@ -23,6 +24,7 @@ scale = { package = "parity-scale-codec", version = "2.1", default-features = fa
[features]
default = ["std"]
std = [
"bitvec/std",
"scale/std",
]
derive = [
Expand All @@ -32,6 +34,10 @@ derive = [
decode = [
"scale/full"
]
# enables type information for bitvec types, matching the name of the parity-scale-codec feature
bit-vec = [
"bitvec"
]

[workspace]
members = [
Expand Down
37 changes: 37 additions & 0 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,40 @@ where
TypeDefCompact::new(MetaType::new::<T>()).into()
}
}

#[cfg(feature = "bit-vec")]
mod bit_vec {
use super::*;

impl<O, T> TypeInfo for bitvec::vec::BitVec<O, T>
where
O: bitvec::order::BitOrder + TypeInfo + 'static,
T: bitvec::store::BitStore + TypeInfo + 'static,
{
type Identity = Self;

fn type_info() -> Type {
crate::TypeDefBitSequence::new::<O, T>().into()
}
}

impl TypeInfo for bitvec::order::Lsb0 {
type Identity = Self;

fn type_info() -> Type {
Type::builder()
.path(Path::new("Lsb0", "bitvec::order"))
.composite(Fields::unit())
}
}

impl TypeInfo for bitvec::order::Msb0 {
type Identity = Self;

fn type_info() -> Type {
Type::builder()
.path(Path::new("Msb0", "bitvec::order"))
.composite(Fields::unit())
}
}
}
27 changes: 27 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,33 @@ fn collections() {
);
}

#[cfg(feature = "bit-vec")]
#[test]
fn bitvec() {
use bitvec::{
order::{
Lsb0,
Msb0,
},
vec::BitVec,
};

assert_type!(
BitVec<Lsb0, u8>,
TypeDefBitSequence::new::<Lsb0, u8>()
);

assert_type!(
BitVec<Msb0, u16>,
TypeDefBitSequence::new::<Msb0, u16>()
);

assert_type!(
BitVec<Msb0, u32>,
TypeDefBitSequence::new::<Msb0, u32>()
);
}

#[test]
fn scale_compact_types() {
assert_type!(Compact<i32>, TypeDefCompact::new(meta_type::<i32>()))
Expand Down
61 changes: 61 additions & 0 deletions src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ impl_from_type_def_for_type!(
TypeDefTuple,
TypeDefCompact,
TypeDefPhantom,
TypeDefBitSequence,
);

impl Type {
Expand Down Expand Up @@ -197,6 +198,8 @@ pub enum TypeDef<T: Form = MetaForm> {
Compact(TypeDefCompact<T>),
/// A PhantomData type.
Phantom(TypeDefPhantom<T>),
/// A type representing a sequence of bits.
BitSequence(TypeDefBitSequence<T>),
}

impl IntoPortable for TypeDef {
Expand All @@ -212,6 +215,7 @@ impl IntoPortable for TypeDef {
TypeDef::Primitive(primitive) => primitive.into(),
TypeDef::Compact(compact) => compact.into_portable(registry).into(),
TypeDef::Phantom(phantom) => phantom.into_portable(registry).into(),
TypeDef::BitSequence(bitseq) => bitseq.into_portable(registry).into(),
}
}
}
Expand Down Expand Up @@ -485,3 +489,60 @@ where
&self.type_param
}
}

/// Type describing a [`bitvec::vec::BitVec`].
///
/// # Note
///
/// This can only be constructed for `TypeInfo` in the `MetaForm` with the `bit-vec` feature
/// enabled, but can be decoded or deserialized into the `PortableForm` without this feature.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Debug)]
pub struct TypeDefBitSequence<T: Form = MetaForm> {
/// The type implementing [`bitvec::store::BitStore`].
bit_store_type: T::Type,
/// The type implementing [`bitvec::order::BitOrder`].
bit_order_type: T::Type,
}

impl IntoPortable for TypeDefBitSequence {
type Output = TypeDefBitSequence<PortableForm>;

fn into_portable(self, registry: &mut Registry) -> Self::Output {
TypeDefBitSequence {
bit_store_type: registry.register_type(&self.bit_store_type),
bit_order_type: registry.register_type(&self.bit_order_type),
}
}
}

impl<T> TypeDefBitSequence<T>
where
T: Form,
{
/// Returns the type of the bit ordering of the [`::bitvec::vec::BitVec`].
pub fn bit_order_type(&self) -> &T::Type {
&self.bit_order_type
}

/// Returns underlying type used to store the [`::bitvec::vec::BitVec`].
pub fn bit_store_type(&self) -> &T::Type {
&self.bit_store_type
}
}

#[cfg(feature = "bit-vec")]
impl TypeDefBitSequence {
/// Creates a new [`TypeDefBitSequence`] for the supplied bit order and bit store types.
pub fn new<O, T>() -> Self
where
O: bitvec::order::BitOrder + TypeInfo + 'static,
T: bitvec::store::BitStore + TypeInfo + 'static,
{
Self {
bit_order_type: MetaType::new::<O>(),
bit_store_type: MetaType::new::<T>(),
}
}
}