use bitfields::bitfield;
#[repr(u8)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum BdecodeTokenType {
Dict = 0,
List,
Str,
Int,
End,
}
impl BdecodeTokenType {
pub const fn from_bits(bits: u8) -> Self {
match bits {
0 => Self::Dict,
1 => Self::List,
2 => Self::Str,
3 => Self::Int,
4 => Self::End,
_ => panic!("Invalid BdecodeTokenType bits"),
}
}
pub const fn into_bits(self) -> u8 {
self as u8
}
}
#[bitfield(u64)]
pub struct BdecodeToken {
#[bits(29)]
offset: u32,
#[bits(3)]
node_type: BdecodeTokenType,
#[bits(29)]
next_item: u32,
#[bits(3)]
header_size: u8,
}
impl BdecodeToken {
pub fn new_all(offset: u32, node_type: BdecodeTokenType, next_item: u32, head_size: u8) -> Self {
BdecodeTokenBuilder::new()
.with_offset(offset)
.with_node_type(node_type)
.with_next_item(next_item)
.with_header_size(head_size)
.build()
}
pub fn new_dict(offset: u32, next_item: u32) -> Self {
Self::new_all(offset, BdecodeTokenType::Dict, next_item, 0)
}
pub fn new_list(offset: u32, next_item: u32) -> Self {
Self::new_all(offset, BdecodeTokenType::List, next_item, 0)
}
pub fn new_int(offset: u32) -> Self {
let next_item = 1;
Self::new_all(offset, BdecodeTokenType::Int, next_item, 0)
}
pub fn new_end(offset: u32) -> Self {
let next_item = 1;
Self::new_all(offset, BdecodeTokenType::End, next_item, 0)
}
pub fn new_str(offset: u32, head_size: u8) -> Self {
let next_item = 1;
Self::new_all(offset, BdecodeTokenType::Str, next_item, head_size)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_token_type() {
assert_eq!(BdecodeTokenType::from_bits(0), BdecodeTokenType::Dict);
assert_eq!(0, BdecodeTokenType::from_bits(0) as u8);
}
}