Rust 如何编写一个宏,将字节拆分为用户指定计数的位元组?

Rust 如何编写一个宏,将字节拆分为用户指定计数的位元组?,rust,macros,rust-macros,Rust,Macros,Rust Macros,我想让宏使用位读取器板条箱将一个字节拆分为2-8个u8部分的元组 我通过以下代码实现了这一点: 使用bitreader::bitreader; 性状元组{ 类型结果类型; fn prepend(self,t:t)->self::ResultType; } 宏规则!impl\u tuple\u prepend{ ( () ) => {}; ($t0:ident$(,$types:ident)*)=>{ $t0,$($types,)*)的impl Tupleprepend{ 类型ResultType

我想让宏使用
位读取器
板条箱将一个字节拆分为2-8个u8部分的元组

我通过以下代码实现了这一点:

使用bitreader::bitreader;
性状元组{
类型结果类型;
fn prepend(self,t:t)->self::ResultType;
}
宏规则!impl\u tuple\u prepend{
( () ) => {};
($t0:ident$(,$types:ident)*)=>{
$t0,$($types,)*)的impl Tupleprepend{
类型ResultType=(T,$t0,$($types,)*);
fn prepend(self,t:t)->self::ResultType{
设($t0,$($types,)*)=self;
(t,$t0,$($types,)*)
}
}
impl_tuple_prepend!{($($类型),*)}
};
}
执行元组预编!{
(_1, _2, _3, _4, _5, _6, _7, _8)
}
宏规则!分割字节(
($reader:ident,$bytes:expr,$count:expr)=>{{
($reader.read_u8($count).unwrap(),)
}};
($reader:ident,$bytes:expr,$count:expr,$($next_counts:expr),+)=>{{
让head=split_byte!($reader,$bytes,$count);
让tail=split_byte!($reader,$bytes,$($next_counts),+);
尾部预弯(头部0)
}};
($bytes:expr$,$count:expr)*)=>{{
让mut reader=BitReader::new($bytes);
拆分字节!(读卡器,$bytes$(,$count)+)
}};
);
现在,我可以使用以下代码:

让buf:&[u8]=&[0x72];
让(比特1、比特2、比特3到8)=拆分字节!(&buf,1,1,6);

有没有办法避免使用
Tupleprepend
trait,在最坏的情况下只创建1个元组而不是8个元组?

因为位宽度的数量直接对应于返回值的数量,所以我会使用泛型和数组来解决这个问题。宏的存在只是为了删除键入的
[]
,我认为这不值得

fn分割字节
  • 如果可以针对夜间生锈,我会使用不稳定的
    min\u const\u泛型
    功能:

    #![特征(最小常数/泛型)]
    fn拆分字节(b:u8,位宽度:[u8;N])->[u8;N]{
    让mut result=[0;N];
    让mut start=0;
    对于(idx,&width),以位_widths.iter()为单位。枚举(){
    让移位=b>>(8-宽度-开始);
    设掩码=(0..width).折叠(0,| a,|(a)(拆分字节($b,[$($w),+]);
    }
    fn main(){
    设[bit1,bit2,bits3_到_8]=拆分_字节!(0b1010_1010,1,1,6);
    断言(第1位,0b1);
    断言(比特2,0b0);
    assert_eq!(位3_至_8,0b10_1010);
    }
    
    另见:


    因为位宽度的数量直接对应于返回值的数量,所以我会使用泛型和数组来解决这个问题。宏的存在只是为了删除
    []
    的类型,我认为这不值得

    fn分割字节
    
  • 如果可以针对夜间生锈,我会使用不稳定的
    min\u const\u泛型
    功能:

    ![feature(最小常量)]
    fn拆分字节(b:u8,位宽度:[u8;N])->[u8;N]{
    让mut result=[0;N];
    让mut start=0;
    对于(idx,&width),以位_widths.iter()为单位。枚举(){
    让移位=b>>(8-宽度-开始);
    设掩码=(0..width).折叠(0,| a,|(a)(拆分字节($b,[$($w),+]);
    }
    fn main(){
    设[bit1,bit2,bits3_到_8]=拆分_字节!(0b1010_1010,1,1,6);
    断言(第1位,0b1);
    断言(比特2,0b0);
    assert_eq!(位3_至_8,0b10_1010);
    }
    
    另见:


    为什么要在调用站点使用宏?只使用一个trait,你就可以做
    let(b1,b2,b3_8)=0x72.split_byte()
    。对不起,我说得不够清楚。我希望有可能在每种可能的组合中拆分向量。也就是说,
    split_byte!(&[0x72],3,2)
    将给我一个由前3个字节和后2个字节创建的两元素元组。该片(这里没有向量)中只有一个值。数字是什么类型?
    u8
    i128
    ?它是
    u8
    类型。如果它是
    u8
    则只有一个字节开始,因此无法获得“前3”或“下2”字节。为什么要在调用站点使用宏呢?只使用一个trait,你就可以做
    let(b1,b2,b3_8)=0x72.split_byte()
    。对不起,我说得不够清楚。我希望有可能在每种可能的组合中拆分一个向量。也就是说,
    split_byte!(&[0x72],3,2)
    将给我一个由前3个字节和后2个字节创建的两元素元组。该片(这里没有向量)中只有一个值。数字是什么类型?
    u8
    i128
    ?它是
    u8
    类型。如果它是
    u8
    则只有一个字节开始,因此无法获得“前3”或“下2”字节。