aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/.gitignore1
-rw-r--r--rust/Cargo.lock7
-rw-r--r--rust/Cargo.toml6
-rw-r--r--rust/src/lib.rs131
4 files changed, 145 insertions, 0 deletions
diff --git a/rust/.gitignore b/rust/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/rust/.gitignore
@@ -0,0 +1 @@
/target
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
new file mode 100644
index 0000000..013989c
--- /dev/null
+++ b/rust/Cargo.lock
@@ -0,0 +1,7 @@
1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing.
3version = 4
4
5[[package]]
6name = "gats"
7version = "0.1.0"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
new file mode 100644
index 0000000..d8b03fe
--- /dev/null
+++ b/rust/Cargo.toml
@@ -0,0 +1,6 @@
1[package]
2name = "gats"
3version = "0.1.0"
4edition = "2024"
5
6[dependencies]
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
new file mode 100644
index 0000000..9b177a1
--- /dev/null
+++ b/rust/src/lib.rs
@@ -0,0 +1,131 @@
1use std::collections::HashMap;
2use std::vec::Vec;
3use std::io::{Write,Read};
4use std::num::FpCategory;
5
6pub enum Value {
7 Integer(i64),
8 ByteString(Vec<u8>),
9 Boolean(bool),
10 List(Vec<Value>),
11 Dictionary(HashMap<String, Value>),
12 Float(f64),
13 Nothing,
14}
15
16// const FLOAT_DIVISOR: f64 = (256_f64).ln();
17
18fn write_packed_int( x: i64 ) -> Vec<u8>
19{
20 let mut w = Vec::<u8>::with_capacity(10);
21 let mut v = x;
22 let mut bb = if x < 0 {
23 v = -v;
24 0x40_u8
25 } else {
26 0x00_u8
27 } | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 };
28 w.push(bb);
29 v = v >> 6;
30 while v > 0 {
31 bb = (v & 0x7F) as u8 | if v > (v & 0x7F) { 0x80_u8 } else { 0x00_u8 };
32 w.push(bb);
33 v = v >> 7;
34 }
35
36 w
37}
38
39fn read_packed_int<R: Read>( r: &mut R ) -> Result<i64, std::io::Error> {
40 let mut out : i64;
41 let mut bb = [0u8];
42 r.read( &mut bb )?;
43 let negative = (bb[0]&0x40_u8) == 0x40_u8;
44 out = (bb[0]&0x3F_u8) as i64;
45 let mut c = 0;
46 while (bb[0]&0x80_u8) != 0 {
47 r.read( &mut bb )?;
48 out |= ((bb[0]&0x7F_u8) as i64) << (6+7*c);
49 c += 1;
50 }
51
52 if negative {
53 Ok(-out)
54 } else {
55 Ok(out)
56 }
57}
58
59impl Value {
60 pub fn write<W: Write>(&self, w: &mut W) -> Result<(), std::io::Error> {
61 match self {
62 Self::Integer(x) => {
63 let mut bb = [0u8];
64 bb[0] = 'i' as u8;
65 w.write_all(&bb)?;
66 w.write_all(&write_packed_int( *x ))?;
67 },
68 Self::ByteString(s) => {
69 let mut bb = [0u8];
70 bb[0] = 's' as u8;
71 w.write_all(&bb)?;
72 w.write_all(&write_packed_int( s.len() as i64 ))?;
73 w.write_all( &s )?;
74 },
75 Self::Boolean(b) => {
76 let mut bb = [0u8];
77 bb[0] = if *b { '1' } else { '0' } as u8;
78 w.write_all( &bb )?;
79 },
80 Self::List(l) => {
81 },
82 Self::Dictionary(d) => {
83 },
84 Self::Float(f) => {
85 let mut bb = ['F' as u8, 0u8];
86 match f.classify() {
87 FpCategory::Nan => {
88 bb[1] = if f.is_sign_negative() { 'N' } else { 'n' } as u8;
89 w.write_all( &bb )?;
90 },
91 FpCategory::Infinite => {
92 bb[1] = if f.is_sign_negative() { 'I' } else { 'i' } as u8;
93 w.write_all( &bb )?;
94 },
95 FpCategory::Zero => {
96 bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8;
97 w.write_all( &bb )?;
98 },
99 FpCategory::Subnormal => {
100 // The format doesn't account for these...uh...make them zero?
101 bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8;
102 w.write_all( &bb )?;
103 },
104 FpCategory::Normal => {
105 let div = 256f64.ln();
106 todo!();
107
108 },
109 }
110 },
111 Self::Nothing => {
112 },
113 }
114 Ok(())
115 }
116}
117
118pub fn add(left: u64, right: u64) -> u64 {
119 left + right
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn it_works() {
128 let result = add(2, 2);
129 assert_eq!(result, 4);
130 }
131}