Skip to main content

yglnk_core/
lib.rs

1#![no_std]
2#![forbid(unsafe_code)]
3
4#[cfg(feature = "alloc")]
5extern crate alloc;
6
7pub use int_enum::{IntEnum, IntEnumError};
8
9pub mod hash_table;
10pub mod hilbert;
11pub mod linear_table;
12
13pub const MAGIC: [u8; 4] = [b'Y', b'g', b'L', b'n'];
14
15#[derive(Clone, Copy, Debug, IntEnum)]
16#[repr(u32)]
17#[rustfmt::skip]
18pub enum FileType {
19    None        = 0x0000_0000,
20    Text        = 0x0000_0001,
21}
22
23#[derive(Clone, Copy, Debug)]
24pub struct FileHeader {
25    pub magic: [u8; 4],
26    pub generator: u32,
27    pub typ: u32,
28    pub version: u32,
29}
30
31impl FileHeader {
32    pub fn decode(data: [u8; 16]) -> Self {
33        Self {
34            magic: data[0..4].try_into().unwrap(),
35            generator: u32::from_be_bytes(data[4..8].try_into().unwrap()),
36            typ: u32::from_be_bytes(data[8..12].try_into().unwrap()),
37            version: u32::from_be_bytes(data[12..16].try_into().unwrap()),
38        }
39    }
40
41    pub fn encode(&self) -> [u8; 16] {
42        let mut data = [0u8; 16];
43        data[0..4].copy_from_slice(&self.magic);
44        data[4..8].copy_from_slice(&u32::to_be_bytes(self.generator));
45        data[8..12].copy_from_slice(&u32::to_be_bytes(self.typ));
46        data[12..16].copy_from_slice(&u32::to_be_bytes(self.version));
47        data
48    }
49}
50
51#[derive(Clone, Copy, Debug, IntEnum)]
52#[repr(u32)]
53#[rustfmt::skip]
54pub enum Type {
55    PlainText   = 0x0000_0000,
56    NestedText  = 0x0000_0001,
57
58    StringTable = 0x0000_0010,
59    LinearPlain = 0x0000_0012,
60
61    HashPlain   = 0x0000_0020,
62    HashLink    = 0x0000_0021,
63
64    X2dhcPlain  = 0x0000_0030,
65    X2dhcLink   = 0x0000_0031,
66}
67
68#[derive(Clone, Copy, Debug, IntEnum)]
69#[repr(u16)]
70#[rustfmt::skip]
71pub enum Ntt01 {
72    Div         = 0x0000,
73    Group       = 0x0001,
74    Header      = 0x0002,
75    Quote       = 0x0003,
76    Code        = 0x0004,
77}
78
79pub fn trunc_key_at0(key: &[u8]) -> &[u8] {
80    memchr::memchr(0, key)
81        .map(|key_end| &key[..key_end])
82        .unwrap_or(key)
83}
84
85#[inline]
86pub fn decode_location(location: u32) -> Option<usize> {
87    usize::try_from(location).ok()?.checked_mul(16)
88}
89
90/// A reference to a string table, including its data and location
91#[derive(Clone, Copy)]
92pub struct StrtabDescriptorRef<'a> {
93    pub data: &'a [u8],
94
95    /// as usual for yglnk, the location is specified in 16-byte units
96    pub location: u32,
97}
98
99impl core::ops::Index<u32> for StrtabDescriptorRef<'_> {
100    type Output = [u8];
101
102    fn index(&self, index: u32) -> &[u8] {
103        trunc_key_at0(&self.data[index.try_into().unwrap()..])
104    }
105}