diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7cd8db7715df9d5fb664e8f95483addc80403503..6f6ba08a06ed287e3b64ca9bdf6ee6561701860a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -12,12 +12,40 @@ ], "problemMatcher": [ "$rustc" - ] + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "cargo run --example example", + "command": "cargo run --example example", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "cargo run --example example2", + "command": "cargo run --example example2", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } }, { "type": "shell", - "label": "cargo build --example example", - "command": "cargo build --example example", + "label": "cargo run --example example3", + "command": "cargo run --example example3", "problemMatcher": [ "$rustc" ], diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..774c9a36b1562c36001ad6d3fc26972ab9321179 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# ArrayDebug + +A newtype over array, providing `fmt::Debug` formatting for generic sized arrays. + +Requires nightly compiler as relying on `#![feature(unsize)]` (awaiting const generics). + +## Usage + +``` rust +extern crate array_debug; + +use array_debug::ArrayDebug; + +#[derive(Debug)] +struct RegisterBlock { + primitive: u32, + small: ArrayDebug<[u32; 3], u32>, + big: ArrayDebug<[u32; 44], u32>, +} + +fn main() { + let t = ArrayDebug::new([1, 2, 3]); + println!("<=32 :{:?}", t); + + let t = ArrayDebug::new([1; 33]); + println!(">32 :{:?}", t); + + let r = RegisterBlock { + primitive: 7, + small: ArrayDebug::new([1, 3, 4]), + big: ArrayDebug::new([8; 44]), + }; + + println!("r :{:?}", r); +} +``` \ No newline at end of file diff --git a/examples/example.rs b/examples/example.rs index ac46ecf0a681f56473b5a1167416dad842aae0b8..7ab9f1afb7c8e8d9f8f4c6cf019467e7cf5bf94d 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -23,6 +23,4 @@ fn main() { }; println!("r :{:?}", r); - - println!("here"); } diff --git a/examples/example2.rs b/examples/example2.rs new file mode 100644 index 0000000000000000000000000000000000000000..ee4ad77cf78af18d74e099d3c2367955d671ada3 --- /dev/null +++ b/examples/example2.rs @@ -0,0 +1,30 @@ +extern crate array_debug; + +use array_debug::ArrayDebug; +use core::mem::transmute; + +#[derive(Debug)] +#[repr(C)] +struct RegisterBlockDebug { + primitive: u32, + small: ArrayDebug<[u32; 3], u32>, + big: ArrayDebug<[u32; 44], u32>, +} + +#[repr(C)] +struct RegisterBlockNative { + primitive: u32, + small: [u32; 3], + big: [u32; 44], +} + +fn main() { + let r = RegisterBlockNative { + primitive: 7, + small: [1, 3, 4], + big: [8; 44], + }; + + let r: RegisterBlockDebug = unsafe { transmute::<_, _>(r) }; + println!("r :{:?}", r); +} diff --git a/examples/example3.rs b/examples/example3.rs new file mode 100644 index 0000000000000000000000000000000000000000..b57056e826f83a5610bba35b54a5739c8e9d85fe --- /dev/null +++ b/examples/example3.rs @@ -0,0 +1,71 @@ +extern crate array_debug; + +use array_debug::ArrayDebug; +use core::ops::{Deref, DerefMut}; + +#[derive(Debug)] +#[repr(C)] +struct RegisterBlockDebug { + primitive: u32, + small: ArrayDebug<[u32; 3], u32>, + big: ArrayDebug<[u32; 44], u32>, +} + +#[repr(C)] +struct RegisterBlockNative { + primitive: u32, + small: [u32; 3], + big: [u32; 44], +} + +fn main() { + let mut r = RegisterBlockDebug { + primitive: 7, + small: ArrayDebug::new([1, 3, 4]), + big: ArrayDebug::new([8; 44]), + }; + + r.small[1] = 7; + println!("r :{:?}", r); + + // auto deref coersion of ArrayDebug + let t: &[u32] = &r.small; + + for i in t { + println!("{}", i); + } + + // explicit deref required + for i in *r.small { + println!("{}", i); + } + + // explicit deref required + for i in r.small.deref() { + println!("{}", i); + } + + + for i in r.small.iter() { + println!("{}", i); + } + + let r = RegisterBlockNative { + primitive: 7, + small: [1, 3, 4], + big: [8; 44], + }; + + for i in &r.small { + println!("{}", i); + } + + for i in r.small.iter() { + println!("{}", i); + } + + let small = [1, 2, 3]; + for i in &small { + println!("{}", i); + } +} diff --git a/src/lib.rs b/src/lib.rs index ce4d69e7bd8102ef3b4f5486e2fa5548fa1c3867..ee2ef831f27f8a86d9ec53249e19645ebf72ae8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![feature(unsize)] use core::iter::Iterator; +use core::ops::{Deref, DerefMut}; use core::{fmt, marker::PhantomData, marker::Unsize}; pub struct ArrayDebug<A, T>(A, PhantomData<T>) @@ -18,6 +19,28 @@ where } } +impl<A, T> Deref for ArrayDebug<A, T> +where + A: Unsize<[T]>, + T: fmt::Debug, +{ + type Target = [T]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<A, T> DerefMut for ArrayDebug<A, T> +where + A: Unsize<[T]>, + T: fmt::Debug, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + impl<A, T> fmt::Debug for ArrayDebug<A, T> where A: Unsize<[T]>, diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 8b1c16ff73bcd4dc45938db02e61aea1321ef38c..0000000000000000000000000000000000000000 --- a/src/main.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![feature(unsize)] - -use core::iter::Iterator; -use core::{fmt, marker::PhantomData, marker::Unsize}; - -struct ArrayDebug<A, T>(A, PhantomData<T>) -where - A: Unsize<[T]>, - T: fmt::Debug; - -impl<A, T> fmt::Debug for ArrayDebug<A, T> -where - A: Unsize<[T]>, - T: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let slice: &[T] = &self.0; - let mut slice = slice.iter().peekable(); - f.write_fmt(format_args!("["))?; - while let Some(i) = slice.next() { - f.write_fmt(format_args!("{:?}", i))?; - if slice.peek().is_some() { - f.write_fmt(format_args!(", "))?; - } - } - f.write_fmt(format_args!("]")) - } -} - -// example -#[derive(Debug)] -struct RegisterBlock { - primitive: u32, - small: ArrayDebug<[u32; 3], u32>, - big: ArrayDebug<[u32; 44], u32>, -} - -fn main() { - let t = ArrayDebug([1, 2, 3], PhantomData); - println!("<=32 :{:?}", t); - - let t = ArrayDebug([1; 33], PhantomData); - println!(">32 :{:?}", t); - - let r = RegisterBlock { - primitive: 7, - small: ArrayDebug([1, 3, 4], PhantomData), - big: ArrayDebug([8; 44], PhantomData), - }; - - println!("r :{:?}", r); -}