### starts_with example: prefix checks Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use starts_with to check if a slice starts with a given prefix. The example asserts true for valid prefixes and false for invalid ones. ```rust let v = [10, 40, 30]; assert!(v.starts_with(&[10])); assert!(v.starts_with(&[10, 40])); assert!(v.starts_with(&v)); assert!(!v.starts_with(&[50])); assert!(!v.starts_with(&[10, 50])); ``` -------------------------------- ### get method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the get method on a slice. It returns a reference to an element or subslice, or None if out of bounds. ```rust let v = [10, 40, 30]; assert_eq!(Some(&10), v.get(1)); assert_eq!(Some(&[10, 40][..]), v.get(0..2)); assert_eq!(None, v.get(3)); assert_eq!(None, v.get(0..4)); ``` -------------------------------- ### join() examples Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Illustrates the `join` method, which flattens a slice and inserts a separator between elements. The examples cover string, integer, and slice separators. ```rust assert_eq!(["hello", "world"].join(" "), "hello world"); assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]); ``` -------------------------------- ### as_simd example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows as_simd usage with a nightly feature flag. The example splits a short slice and computes a SIMD sum, asserting the result. ```rust #![feature(portable_simd)] use core::simd::prelude::*; let short = &[1, 2, 3]; let (prefix, middle, suffix) = short.as_simd::<4>(); assert_eq!(middle, []); // Not enough elements for anything in the middle // They might be split in any possible way between prefix and suffix let it = prefix.iter().chain(suffix).copied(); assert_eq!(it.collect::>(), vec![1, 2, 3]); fn basic_simd_sum(x: &[f32]) -> f32 { use std::ops::Add; let (prefix, middle, suffix) = x.as_simd(); let sums = f32x4::from_array([ prefix.iter().copied().sum(), 0.0, 0.0, suffix.iter().copied().sum(), ]); let sums = middle.iter().copied().fold(sums, f32x4::add); sums.reduce_sum() } let numbers: Vec = (1..101).map(|x| x as _).collect(); assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0); ``` -------------------------------- ### connect() deprecated examples Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows the deprecated `connect` method, which is renamed to `join`. The examples demonstrate string and integer separators. ```rust assert_eq!(["hello", "world"].connect(" "), "hello world"); assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); ``` -------------------------------- ### windows example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates the `windows` method, which returns an iterator over overlapping contiguous windows of a given size. The example shows that for a slice of length 5 and window size 3, the iterator yields three windows and then `None`. ```rust let slice = ['l', 'o', 'r', 'e', 'm']; let mut iter = slice.windows(3); assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']); assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']); assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']); assert!(iter.next().is_none()); ``` -------------------------------- ### binary_search_by_key example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use binary_search_by_key on a slice of pairs sorted by their second element. The example asserts found and not-found results, including a range match for a key with multiple matches. ```rust let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1), (1, 2), (2, 3), (4, 5), (5, 8), (3, 13), (1, 21), (2, 34), (4, 55)]; assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9)); assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7)); assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13)); let r = s.binary_search_by_key(&1, |&(a, b)| b); assert!(match r { Ok(1..=4) => true, _ => false, }); ``` -------------------------------- ### align_to example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates align_to on a byte slice, splitting it into prefix, aligned middle, and suffix. The example is wrapped in unsafe because align_to is unsafe. ```rust unsafe { let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7]; let (prefix, shorts, suffix) = bytes.align_to::(); // less_efficient_algorithm_for_bytes(prefix); // more_efficient_algorithm_for_aligned_shorts(shorts); // less_efficient_algorithm_for_bytes(suffix); } ``` -------------------------------- ### iter example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to iterate over a slice using the `iter` method, which yields all items from start to end. The example asserts each successive `next()` call returns the expected element, and finally `None` when the iterator is exhausted. ```rust let x = &[1, 2, 4]; let mut iterator = x.iter(); assert_eq!(iterator.next(), Some(&1)); assert_eq!(iterator.next(), Some(&2)); assert_eq!(iterator.next(), Some(&4)); assert_eq!(iterator.next(), None); ``` -------------------------------- ### starts_with example: empty needle Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates that starts_with always returns true when the needle is an empty slice, even for an empty slice. The example checks both a non-empty and an empty slice. ```rust let v = &[10, 40, 30]; assert!(v.starts_with(&[])); let v: &[u8] = &[]; assert!(v.starts_with(&[])); ``` -------------------------------- ### as_bytes example Source: https://docs.rs/hidreport/latest/hidreport/hid/enum.ItemType.html Example of using as_bytes() to convert an ItemType to HID bytes and back using try_from. ```rust let item = ItemType::from(LogicalMinimum::from(128i32)); let bytes = item.as_bytes(); assert_eq!(bytes.len(), 3); // first byte is the LogicalMinimum prefix plus two data bytes for signed 128 assert_eq!(*bytes.get(0).unwrap(), 0b00010100 + 2); assert_eq!(*bytes.get(1).unwrap(), 128); assert_eq!(*bytes.get(2).unwrap(), 0); let item2 = ItemType::try_from(bytes.as_slice()).unwrap(); assert_eq!(item, item2); ``` -------------------------------- ### strip_prefix examples Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates strip_prefix, which returns the subslice after the prefix if present, or None otherwise. Includes a string prefix example. ```rust let v = &[10, 40, 30]; assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..])); assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..])); assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..])); assert_eq!(v.strip_prefix(&[50]), None); assert_eq!(v.strip_prefix(&[10, 50]), None); let prefix : &str = "he"; assert_eq!(b"hello".strip_prefix(prefix.as_bytes()), Some(b"llo".as_ref())); ``` -------------------------------- ### Buggy Usage Page Example Source: https://docs.rs/hidreport/latest/src/hidreport/hid.rs.html This example demonstrates a bug where setting a usage page and a mismatched usage ID results in an unexpected usage value. ```rust # use crate::hidreport::hid::*; use hidreport::types::*; use hidreport::{Field, ReportDescriptor, Report, VariableField, Usage}; use hut::{self, AsUsagePage, AsUsage}; let rdesc = ReportDescriptorBuilder::new() .usage_page(hut::GenericDesktop::X) // sets Usage Page to GenericDesktop .usage_id(hut::Arcade::CoinDoor) // BUG: sets Usage ID to 0x2 .append(LogicalMinimum::from(0).into()) .append(LogicalMaximum::from(128).into()) .append(ReportCount::from(1).into()) .append(ReportSize::from(8).into()) .input(ItemBuilder::new() .variable() .absolute() .input()) .build(); let rdesc: ReportDescriptor = ReportDescriptor::try_from(&rdesc).unwrap(); let input = rdesc.input_reports().first().unwrap(); let item = input.fields().first().unwrap(); let usage: Usage = match item { Field::Variable(VariableField { usage, .. }) => *usage, _ => panic!("Invalid field type"), }; let expected_buggy_usage: Usage = hut::GenericDesktop::Mouse.usage().into(); assert_eq!(usage, expected_buggy_usage); ``` -------------------------------- ### concat() examples Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how `concat` flattens a slice of strings or nested arrays into a single value. The examples are from the documentation for the `concat` method. ```rust assert_eq!(["hello", "world"].concat(), "helloworld"); assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); ``` -------------------------------- ### windows with Cell example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows an alternative to `windows_mut` using `Cell::as_slice_of_cells` to mutate overlapping windows safely. The example swaps the first and last elements of each window of size 3, resulting in a reversed order of the original array. ```rust use std::cell::Cell; let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5']; let slice = &mut array[..]; let slice_of_cells: &[Cell] = Cell::from_mut(slice).as_slice_of_cells(); for w in slice_of_cells.windows(3) { Cell::swap(&w[0], &w[2]); } assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']); ``` -------------------------------- ### first method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the first method on a slice. It returns the first element of the slice, or None if it is empty. ```rust let v = [10, 40, 30]; assert_eq!(Some(&10), v.first()); let w: &[i32] = &[]; assert_eq!(None, w.first()); ``` -------------------------------- ### split_first method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the split_first method on a slice. It returns the first and all the rest of the elements, or None if empty. ```rust let x = &[0, 1, 2]; if let Some((first, elements)) = x.split_first() { assert_eq!(first, &0); assert_eq!(elements, &[1, 2]); } ``` -------------------------------- ### repeat() example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Verifies that repeating a slice three times produces the expected vector. This example is from the documentation for the `repeat` method on slices. ```rust assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]); ``` -------------------------------- ### windows shorter than size example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows that `windows` returns no values when the slice is shorter than the requested window size. The example uses a slice of length 3 and window size 4, and asserts that the iterator immediately yields `None`. ```rust let slice = ['f', 'o', 'o']; let mut iter = slice.windows(4); assert!(iter.next().is_none()); ``` -------------------------------- ### split_once example: nightly feature Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates the nightly-only split_once method, which splits on the first matching element and returns the prefix and suffix. The example shows a match and a non-match case, requiring the slice_split_once feature. ```rust #![feature(slice_split_once)] let s = [1, 2, 3, 2, 4]; assert_eq!(s.split_once(|&x| x == 2), Some(( &[1][..], &[3, 2, 4][..] ))); assert_eq!(s.split_once(|&x| x == 0), None); ``` -------------------------------- ### Common ItemBuilder usage patterns Source: https://docs.rs/hidreport/latest/src/hidreport/hid.rs.html Examples of creating InputItem, OutputItem, and FeatureItem instances using the ItemBuilder fluent API. ```rust # use crate::hidreport::hid::*; let item: InputItem = ItemBuilder::new() .variable() .absolute() .input(); let item: OutputItem = ItemBuilder::new() .constant() .output(); let item: FeatureItem = ItemBuilder::new() .array() .relative() .feature(); ``` -------------------------------- ### is_sorted_by_key: key extraction examples Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use `is_sorted_by_key` with a key extraction function. The first example checks sorting by string length; the second checks sorting by absolute value, which fails because `-2` and `-1` have the same absolute value. ```rust assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len())); assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); ``` -------------------------------- ### Building a Report Descriptor Source: https://docs.rs/hidreport/latest/src/hidreport/hid.rs.html Example of using ReportDescriptorBuilder to construct a mouse report descriptor. ```rust let mut builder = ReportDescriptorBuilder::new(); let rdesc: Vec = builder .usage_page(hut::UsagePage::GenericDesktop) .usage_id(hut::GenericDesktop::Mouse) .open_collection(CollectionItem::Application) .open_collection(CollectionItem::Physical) .push() .append(LogicalMinimum::from(0).into()) .append(LogicalMaximum::from(128).into()) .pop() .append(ReportCount::from(2).into()) .append(ReportSize::from(8).into()) .usage_id(hut::GenericDesktop::X) .usage_id(hut::GenericDesktop::Y) .input(ItemBuilder::new() .variable() .absolute() .input()) .close_collection() .close_collection() .build(); ``` -------------------------------- ### as_ptr example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use `as_ptr` to obtain a raw pointer to the slice's buffer and then iterate over the elements using pointer arithmetic. The example asserts that each element accessed via `get_unchecked` matches the value at the corresponding pointer offset. ```rust let x = &[1, 2, 4]; let x_ptr = x.as_ptr(); unsafe { for i in 0..x.len() { assert_eq!(x.get_unchecked(i), &*x_ptr.add(i)); } } ``` -------------------------------- ### subslice_range basic usage Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use `subslice_range` with `split` to get the index ranges of each subslice. The example uses `core::range::Range` and asserts the expected ranges for a slice split on zeros. ```rust use core::range::Range; let nums = &[0, 5, 10, 0, 0, 5]; let mut iter = nums .split(|t| *t == 0) .map(|n| nums.subslice_range(n).unwrap()); assert_eq!(iter.next(), Some(Range { start: 0, end: 0 })); assert_eq!(iter.next(), Some(Range { start: 1, end: 3 })); assert_eq!(iter.next(), Some(Range { start: 4, end: 4 })); assert_eq!(iter.next(), Some(Range { start: 5, end: 6 })); ``` -------------------------------- ### splitn example: split once by divisible by 3 Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use splitn to split a slice into at most n subslices, printing each group. The example splits once by numbers divisible by 3, producing [10, 40] and [20, 60, 50]. ```rust let v = [10, 40, 30, 20, 60, 50]; for group in v.splitn(2, |num| *num % 3 == 0) { println!("{group:?}"); } ``` -------------------------------- ### Example Usage of Item Data Conversion Source: https://docs.rs/hidreport/latest/src/hidreport/hid.rs.html Demonstrates how to extract and convert data from an HID item using try_from. ```rust # fn func(item: impl Item) { if let Some(data) = item.data() { let value: u32 = u32::try_from(&data).unwrap(); } # } ``` -------------------------------- ### binary_search_by example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates binary_search_by with a comparator closure. The comparator uses `probe.cmp(&seek)` to compare each element. Results are the same as the binary_search example: found at index 9, not found at 7 and 13, and the match for 1 can be any index in [1, 4]. ```rust let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; let seek = 13; assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9)); let seek = 4; assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7)); let seek = 100; assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13)); let seek = 1; let r = s.binary_search_by(|probe| probe.cmp(&seek)); assert!(match r { Ok(1..=4) => true, _ => false, }); ``` -------------------------------- ### first_chunk method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the first_chunk method on a slice. It returns an array reference to the first N items, or None if the slice is too short. ```rust let u = [10, 40, 30]; assert_eq!(Some(&[10, 40]), u.first_chunk::<2>()); let v: &[i32] = &[10]; assert_eq!(None, v.first_chunk::<2>()); let w: &[i32] = &[]; assert_eq!(Some(&[]), w.first_chunk::<0>()); ``` -------------------------------- ### is_sorted example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Checks is_sorted on various slices, including empty, single-element, and NaN cases. The example asserts expected sortedness results. ```rust let empty: [i32; 0] = []; assert!([1, 2, 2, 9].is_sorted()); assert!(![1, 3, 2, 4].is_sorted()); assert!([0].is_sorted()); assert!(empty.is_sorted()); assert!(![0.0, 1.0, f32::NAN].is_sorted()); ``` -------------------------------- ### split_first_chunk method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the split_first_chunk method on a slice. It returns an array reference to the first N items and the remaining slice, or None if the slice is too short. ```rust let x = &[0, 1, 2]; if let Some((first, elements)) = x.split_first_chunk::<2>() { assert_eq!(first, &[0, 1]); assert_eq!(elements, &[2]); } assert_eq!(None, x.split_first_chunk::<4>()); ``` -------------------------------- ### len method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the len method on a slice. It returns the number of elements in the slice. ```rust let a = [1, 2, 3]; assert_eq!(a.len(), 3); ``` -------------------------------- ### is_sorted_by: custom comparator examples Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use `is_sorted_by` with a custom comparator. The comparator must return `true` when `a` is considered less than or equal to `b`. The examples cover non-decreasing order, strict order, single-element slices, and empty slices. ```rust assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b)); assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b)); assert!([0].is_sorted_by(|a, b| true)); assert!([0].is_sorted_by(|a, b| false)); let empty: [i32; 0] = []; assert!(empty.is_sorted_by(|a, b| false)); assert!(empty.is_sorted_by(|a, b| true)); ``` -------------------------------- ### split_last method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the split_last method on a slice. It returns the last and all the rest of the elements, or None if empty. ```rust let x = &[0, 1, 2]; if let Some((last, elements)) = x.split_last() { assert_eq!(last, &2); assert_eq!(elements, &[0, 1]); } ``` -------------------------------- ### last method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the last method on a slice. It returns the last element of the slice, or None if it is empty. ```rust let v = [10, 40, 30]; assert_eq!(Some(&30), v.last()); let w: &[i32] = &[]; assert_eq!(None, w.last()); ``` -------------------------------- ### rsplitn example: split from end by divisible by 3 Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use rsplitn to split a slice from the end into at most n subslices, printing each group. The example splits once by numbers divisible by 3, producing [50] and [10, 40, 30, 20]. ```rust let v = [10, 40, 30, 20, 60, 50]; for group in v.rsplitn(2, |num| *num % 3 == 0) { println!("{group:?}"); } ``` -------------------------------- ### is_empty method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the is_empty method on a slice. It returns true if the slice has a length of 0. ```rust let a = [1, 2, 3]; assert!(!a.is_empty()); let b: &[i32] = &[]; assert!(b.is_empty()); ``` -------------------------------- ### array_windows example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Returns an iterator over overlapping windows of N elements. If N is greater than the slice length, no windows are produced. Panics if N is zero. ```rust let slice = [0, 1, 2, 3]; let mut iter = slice.array_windows(); assert_eq!(iter.next().unwrap(), &[0, 1]); assert_eq!(iter.next().unwrap(), &[1, 2]); assert_eq!(iter.next().unwrap(), &[2, 3]); assert!(iter.next().is_none()); ``` -------------------------------- ### last_chunk method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the last_chunk method on a slice. It returns an array reference to the last N items, or None if the slice is too short. ```rust let u = [10, 40, 30]; assert_eq!(Some(&[40, 30]), u.last_chunk::<2>()); let v: &[i32] = &[10]; assert_eq!(None, v.last_chunk::<2>()); let w: &[i32] = &[]; assert_eq!(Some(&[]), w.last_chunk::<0>()); ``` -------------------------------- ### partition_point range example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to find the whole range of matching items using partition_point. The low and high bounds are computed, and the binary_search result is verified to fall within that range. Also demonstrates that for a not-found value the range is empty. ```rust let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; let low = s.partition_point(|x| x < &1); assert_eq!(low, 1); let high = s.partition_point(|x| x <= &1); assert_eq!(high, 5); let r = s.binary_search(&1); assert!((low..high).contains(&r.unwrap())); assert!(s[..low].iter().all(|&x| x < 1)); assert!(s[low..high].iter().all(|&x| x == 1)); assert!(s[high..].iter().all(|&x| x > 1)); // For something not found, the "range" of equal items is empty assert_eq!(s.partition_point(|x| x < &11), 9); assert_eq!(s.partition_point(|x| x <= &11), 9); assert_eq!(s.binary_search(&11), Err(9)); ``` -------------------------------- ### Example usage of FieldValue with extraction and conversion Source: https://docs.rs/hidreport/latest/hidreport/struct.FieldValue.html Shows how to extract a FieldValue from device bytes and convert it to signed or unsigned types based on the `is_signed()` method. ```rust let bytes: Vec = read_from_device(); let val = field.extract(bytes.as_slice()).unwrap(); if val.is_signed() { let unsigned: u32 = val.into(); } else { let signed: i32 = val.into(); } ``` -------------------------------- ### repeat() panic on overflow Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates a panic when the capacity would overflow. The example is marked with a warning icon and is intended to show the runtime panic behavior. ```rust // this will panic at runtime b"0123456789abcdef".repeat(usize::MAX); ``` -------------------------------- ### as_ptr_range example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Illustrates the use of `as_ptr_range` to get a half-open range of raw pointers spanning the slice. The example checks that a pointer to an element within the slice is contained in the range, while a pointer to a separate value is not. ```rust let a = [1, 2, 3]; let x = &a[1] as *const _; let y = &5 as *const _; assert!(a.as_ptr_range().contains(&x)); assert!(!a.as_ptr_range().contains(&y)); ``` -------------------------------- ### split_last_chunk method example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use the split_last_chunk method on a slice. It returns an array reference to the last N items and the remaining slice, or None if the slice is too short. ```rust let x = &[0, 1, 2]; if let Some((last, elements)) = x.split_last_chunk::<2>() { assert_eq!(last, &[1, 2]); assert_eq!(elements, &[0]); } assert_eq!(None, x.split_last_chunk::<4>()); ``` -------------------------------- ### element_offset: basic usage Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use `element_offset` to get the index of an element reference. Returns `Some(index)` when the reference points to the start of an element. ```rust let nums: &[u32] = &[1, 7, 1, 1]; let num = &nums[2]; assert_eq!(num, &1); assert_eq!(nums.element_offset(num), Some(2)); ``` -------------------------------- ### Set Usage ID with ReportDescriptorBuilder Source: https://docs.rs/hidreport/latest/src/hidreport/hid.rs.html Example of setting the usage page and usage ID. Note that mismatched usage pages and IDs can lead to unexpected results. ```rust use hut::{self, AsUsagePage, AsUsage}; let rdesc = ReportDescriptorBuilder::new() .usage_page(hut::UsagePage::Button) // sets Usage Page to Button .usage_id(hut::GenericDesktop::X) // BUG: sets Usage ID to 0x30 .build(); ``` -------------------------------- ### element_offset: returning None for unaligned element Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows that `element_offset` returns `None` when the reference does not point to the start of an element, even if it points to a valid memory location. The example uses a flattened slice and an unaligned reference. ```rust let arr: &[[u32; 2]] = &[[0, 1], [2, 3]]; let flat_arr: &[u32] = arr.as_flattened(); let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap(); let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap(); assert_eq!(ok_elm, &[0, 1]); assert_eq!(weird_elm, &[1, 2]); assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0 assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1 ``` -------------------------------- ### Extract field values with signedness handling Source: https://docs.rs/hidreport/latest/hidreport/struct.ArrayField.html Example showing how to extract field values from report bytes and convert them to i32 or u32 based on is_signed(). ```rust if field.is_signed() { println!("Signed values: {:?}", field .extract(bytes) .unwrap() .iter() .map(i32::from) .collect::>()); } else { println!("Unsigned values: {:?}", field .extract(bytes) .unwrap() .iter() .map(u32::from) .collect::>()); } ``` -------------------------------- ### ArrayField::extract usage example Source: https://docs.rs/hidreport/latest/src/hidreport/lib.rs.html Example usage of ArrayField::extract to extract values from report bytes, handling signed and unsigned values based on is_signed(). The example is a doc test that uses the hidreport crate. ```rust /// # use hidreport::ArrayField; /// # fn func(field: &ArrayField, bytes: &[u8]) { /// if field.is_signed() { /// println!("Signed values: {:?}", field /// .extract(bytes) /// .unwrap() /// .iter() /// .map(i32::from) /// .collect::>()); /// } else { /// println!("Unsigned values: {:?}", field /// .extract(bytes) /// .unwrap() /// .iter() /// .map(u32::from) /// .collect::>()); /// } /// /// # } ``` -------------------------------- ### Create Usage from page and ID Source: https://docs.rs/hidreport/latest/hidreport/struct.Usage.html Creates a Usage instance from a UsagePage and UsageId. The example uses the Generic Desktop page (0x01) and the Mouse usage ID (0x02). ```rust let up = UsagePage::from(0x01); // Generic Desktop let uid = UsageId::from(0x02); // Mouse let usage = Usage::from_page_and_id(up, uid); ``` -------------------------------- ### contains example: basic usage Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use contains to check if a slice contains a value. The example asserts that 30 is present and 50 is not. ```rust let v = [10, 40, 30]; assert!(v.contains(&30)); assert!(!v.contains(&50)); ``` -------------------------------- ### system() method Source: https://docs.rs/hidreport/latest/src/hidreport/types.rs.html Determines the UnitSystem based on the first nibble of the report. ```rust pub fn system(&self) -> UnitSystem { match self.nibbles().first() { None | Some(0) => UnitSystem::None, Some(1) => UnitSystem::SILinear, Some(2) => UnitSystem::SIRotation, Some(3) => UnitSystem::EnglishLinear, Some(4) => UnitSystem::EnglishRotation, Some(n) => panic!("invalid size {n} for the UnitSystem nibble"), } } ``` -------------------------------- ### rsplit example: split from end Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows how to use rsplit to iterate over subslices from the end, with the matched element excluded. The example asserts the expected subslices and that iteration ends with None. ```rust let slice = [11, 22, 33, 0, 44, 55]; let mut iter = slice.rsplit(|num| *num == 0); assert_eq!(iter.next().unwrap(), &[44, 55]); assert_eq!(iter.next().unwrap(), &[11, 22, 33]); assert_eq!(iter.next(), None); ``` -------------------------------- ### Build HID Report Descriptors Programmatically Source: https://docs.rs/hidreport Shows how to construct a HID Report Descriptor from scratch using the ReportDescriptorBuilder and the hut crate for HID usages. ```rust use hut::{self, AsUsagePage, AsUsage}; let builder = ReportDescriptorBuilder::new(); let rdesc: Vec = builder .append(hut::UsagePage::GenericDesktop.into()) .append(hut::GenericDesktop::Mouse.usage().into()) .open_collection(CollectionItem::Application) .open_collection(CollectionItem::Physical) .push() .append(LogicalMinimum::from(0).into()) .append(LogicalMaximum::from(128).into()) .pop() .append(ReportCount::from(2).into()) .append(ReportSize::from(8).into()) .append(hut::GenericDesktop::X.usage().into()) .append(hut::GenericDesktop::Y.usage().into()) .input(ItemBuilder::new() .variable() .absolute() .input()) .close_collection() .close_collection() .build(); ``` -------------------------------- ### rsplit example: empty slice at edges Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates that rsplit returns an empty slice when the first or last element matches the predicate. The example uses a slice of integers and a predicate checking for even numbers. ```rust let v = &[0, 1, 1, 2, 3, 5, 8]; let mut it = v.rsplit(|n| *n % 2 == 0); assert_eq!(it.next().unwrap(), &[]); assert_eq!(it.next().unwrap(), &[3, 5]); assert_eq!(it.next().unwrap(), &[1, 1]); assert_eq!(it.next().unwrap(), &[]); assert_eq!(it.next(), None); ``` -------------------------------- ### Creating a new ItemBuilder Source: https://docs.rs/hidreport/latest/src/hidreport/hid.rs.html Demonstrates initializing a new builder. Unset flags default to their standard HID values. ```rust # use crate::hidreport::hid::*; let item: InputItem = ItemBuilder::new() .data() .variable() .absolute() .input(); ``` -------------------------------- ### get_unchecked example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates the unsafe `get_unchecked` method on a slice, which returns a reference to an element without bounds checking. The example asserts that `x.get_unchecked(1)` returns `&2`. Calling with an out-of-bounds index is undefined behavior. ```rust let x = &[1, 2, 4]; unsafe { assert_eq!(x.get_unchecked(1), &2); } ``` -------------------------------- ### Construct Usage from UsagePage and UsageId Source: https://docs.rs/hidreport/latest/src/hidreport/types.rs.html Shows how to create a Usage value from a UsagePage and UsageId using the from_page_and_id method. The example uses the hidreport crate and demonstrates the usage of the UsagePage and UsageId types. ```rust /// The 16-bit Usage Page identifier, see Section 5.5 "Usages". /// /// The UsagePage forms the upper 16 bits of a 32-bit [Usage](crate::Usage). /// ``` /// # use hidreport::*; /// let up = UsagePage::from(0x01); // Generic Desktop /// let uid = UsageId::from(0x02); // Mouse /// let usage = Usage::from_page_and_id(up, uid); /// ``` /// For known named usages see the `hut` crate. ``` -------------------------------- ### trim_prefix examples (nightly) Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Nightly-only experimental API (trim_prefix_suffix). Shows trim_prefix, which removes the prefix if present, otherwise returns the original slice. Requires the #![feature(trim_prefix_suffix)] attribute. ```rust #![feature(trim_prefix_suffix)] let v = &[10, 40, 30]; // Prefix present - removes it assert_eq!(v.trim_prefix(&[10]), &[40, 30][..]); assert_eq!(v.trim_prefix(&[10, 40]), &[30][..]); assert_eq!(v.trim_prefix(&[10, 40, 30]), &[][..]); // Prefix absent - returns original slice assert_eq!(v.trim_prefix(&[50]), &[10, 40, 30][..]); assert_eq!(v.trim_prefix(&[10, 50]), &[10, 40, 30][..]); let prefix : &str = "he"; assert_eq!(b"hello".trim_prefix(prefix.as_bytes()), b"llo".as_ref()); ``` -------------------------------- ### Converting Units to u32 and back with UnitSystem handling Source: https://docs.rs/hidreport/latest/hidreport/types/enum.Units.html Shows how to convert a Units value to its u32 byte representation and back to a Unit, demonstrating that Centimeter is non-ambiguous (UnitSystem::SILinear) while Seconds is ambiguous (UnitSystem::None) and requires explicitly setting a system. Also notes that exponents outside the 4-bit twos complement range are ignored and set to zero. ```rust let v = u32::from(Units::Centimeter { exponent: -2 }); let unit = Unit::from(v); assert!(matches!(unit.length(), Units::Centimeter { exponent: -2 })); // Centimeters are non-ambiguous assert!(matches!(unit.system(), UnitSystem::SILinear)); let v = u32::from(Units::Seconds { exponent: 3 }); let unit = Unit::from(v); assert!(matches!(unit.time(), Units::Seconds { exponent: 3 })); // Seconds are ambiguous assert!(matches!(unit.system(), UnitSystem::None)); // Explicitly set a system let v = u32::from(UnitSystem::SILinear) | v; let unit = Unit::from(v); assert!(matches!(unit.time(), Units::Seconds { exponent: 3 })); assert!(matches!(unit.system(), UnitSystem::SILinear)); ``` -------------------------------- ### Buggy usage_page/usage_id mismatch example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorBuilder.html Illustrates a bug where usage_page() sets the Usage Page to GenericDesktop but usage_id() sets the Usage ID to 0x2 (Arcade CoinDoor), resulting in the actual usage being GenericDesktop Mouse. The example builds a descriptor, parses it, and asserts the resulting usage equals the buggy expected usage. ```rust use hidreport::types::*; use hidreport::{Field, ReportDescriptor, Report, VariableField, Usage}; use hut::{self, AsUsagePage, AsUsage}; let rdesc = ReportDescriptorBuilder::new() .usage_page(hut::GenericDesktop::X) // sets Usage Page to GenericDesktop .usage_id(hut::Arcade::CoinDoor) // BUG: sets Usage ID to 0x2 .append(LogicalMinimum::from(0).into()) .append(LogicalMaximum::from(128).into()) .append(ReportCount::from(1).into()) .append(ReportSize::from(8).into()) .input(ItemBuilder::new() .variable() .absolute() .input()) .build(); let rdesc: ReportDescriptor = ReportDescriptor::try_from(&rdesc).unwrap(); let input = rdesc.input_reports().first().unwrap(); let item = input.fields().first().unwrap(); let usage: Usage = match item { Field::Variable(VariableField { usage, .. }) => *usage, _ => panic!("Invalid field type"), }; let expected_buggy_usage: Usage = hut::GenericDesktop::Mouse.usage().into(); assert_eq!(usage, expected_buggy_usage); ``` -------------------------------- ### rsplit usage Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ItemData.html Examples of splitting a slice from the end, working backwards based on a predicate. ```rust let slice = [11, 22, 33, 0, 44, 55]; let mut iter = slice.rsplit(|num| *num == 0); assert_eq!(iter.next().unwrap(), &[44, 55]); assert_eq!(iter.next().unwrap(), &[11, 22, 33]); assert_eq!(iter.next(), None); ``` ```rust let v = &[0, 1, 1, 2, 3, 5, 8]; let mut it = v.rsplit(|n| *n % 2 == 0); assert_eq!(it.next().unwrap(), &[]); assert_eq!(it.next().unwrap(), &[3, 5]); assert_eq!(it.next().unwrap(), &[1, 1]); assert_eq!(it.next().unwrap(), &[]); assert_eq!(it.next(), None); ``` -------------------------------- ### binary_search example Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Demonstrates binary_search on a slice. The first element is found at index 9, the second and third are not found (Err with insertion index), and the fourth could match any position in [1, 4]. ```rust let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; assert_eq!(s.binary_search(&13), Ok(9)); assert_eq!(s.binary_search(&4), Err(7)); assert_eq!(s.binary_search(&100), Err(13)); let r = s.binary_search(&1); assert!(match r { Ok(1..=4) => true, _ => false, }); ``` -------------------------------- ### strip_suffix examples Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ReportDescriptorItems.html Shows strip_suffix, which returns the subslice before the suffix if present, or None otherwise. ```rust let v = &[10, 40, 30]; assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..])); assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..])); assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..])); assert_eq!(v.strip_suffix(&[50]), None); assert_eq!(v.strip_suffix(&[50, 30]), None); ``` -------------------------------- ### get method Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ItemData.html Returns a reference to an element or subslice based on the provided index or range. ```rust let v = [10, 40, 30]; assert_eq!(Some(&40), v.get(1)); assert_eq!(Some(&[10, 40][..]), v.get(0..2)); assert_eq!(None, v.get(3)); assert_eq!(None, v.get(0..4)); ``` -------------------------------- ### iter(&self) -> Iter<'_, T> Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ItemData.html Returns an iterator over the slice, yielding all items from start to end. ```APIDOC ## iter(&self) -> Iter<'_, T> ### Description Returns an iterator over the slice. The iterator yields all items from start to end. ### Method iter ### Signature pub fn iter(&self) -> Iter<'_, T> ### Parameters None ### Return Value Iter<'_, T> - An iterator over the slice elements. ### Examples ```rust let x = &[1, 2, 4]; let mut iterator = x.iter(); assert_eq!(iterator.next(), Some(&1)); assert_eq!(iterator.next(), Some(&2)); assert_eq!(iterator.next(), Some(&4)); assert_eq!(iterator.next(), None); ``` ### Availability 1.0.0 ``` -------------------------------- ### Checking collection type Source: https://docs.rs/hidreport/latest/hidreport/struct.Collection.html Example of accessing a field's collection and checking if it is a physical collection. ```rust let collection = field.collections.first().unwrap(); match collection.collection_type() { CollectionType::Physical => println!("This field is part of a physical collection"), _ => {}, } ``` -------------------------------- ### get Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ItemData.html Returns a reference to an element or subslice depending on the type of index. Returns None if out of bounds. ```APIDOC ## get ### Description Returns a reference to an element or subslice depending on the type of index. If given a position, returns a reference to the element at that position or None if out of bounds. If given a range, returns the subslice corresponding to that range, or None if out of bounds. ### Signature pub fn get(&self, index: I) -> Option<&>::Output> where I: SliceIndex<[T]> ### Parameters - index (I) - The index or range to access. ### Returns - Option<&>::Output> - A reference to the element or subslice, or None if out of bounds. ### Examples ```rust let v = [10, 40, 30]; assert_eq!(Some(&40), v.get(1)); assert_eq!(Some(&[10, 40][..]), v.get(0..2)); assert_eq!(None, v.get(3)); assert_eq!(None, v.get(0..4)); ``` ``` -------------------------------- ### Usage::from_page_and_id Source: https://docs.rs/hidreport/latest/hidreport/struct.Usage.html Creates a Usage instance from a UsagePage and a UsageId. This is the primary constructor for the Usage struct. ```APIDOC ## Usage::from_page_and_id ### Description Creates a Usage from a UsagePage and a UsageId. ### Method pub fn from_page_and_id(usage_page: UsagePage, usage_id: UsageId) -> Usage ### Parameters - **usage_page** (UsagePage) - Required - The usage page, e.g., Generic Desktop (0x01). - **usage_id** (UsageId) - Required - The usage ID, e.g., Mouse (0x02). ### Returns - **Usage** - A new Usage instance. ### Example ```rust let up = UsagePage::from(0x01); // Generic Desktop let uid = UsageId::from(0x02); // Mouse let usage = Usage::from_page_and_id(up, uid); ``` ``` -------------------------------- ### Trim ASCII whitespace from start Source: https://docs.rs/hidreport/latest/hidreport/hid/struct.ItemData.html Removes leading ASCII whitespace bytes from the byte slice. ```rust assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n"); assert_eq!(b" ".trim_ascii_start(), b""); assert_eq!(b"".trim_ascii_start(), b""); ``` -------------------------------- ### Pseudo-report descriptor with usage range and individual usages Source: https://docs.rs/hidreport/latest/hidreport/struct.ArrayField.html Example pseudo-report descriptor showing an ArrayField with a usage range first, then one with individual usages. Used to illustrate is_usage_range(). ```text UsageMinimum (0) UsageMaximum (255) Input (Array) Usage (Tip Switch) Usage (Barrel Switch) Usage (Secondary Barrel Switch) Input (Array) ```