create-sia-app 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/package.json +2 -6
  2. package/template/AGENTS.md +143 -0
  3. package/template/CLAUDE.md +25 -46
  4. package/template/README.md +6 -12
  5. package/template/_gitignore +0 -1
  6. package/template/dist/assets/index-BEylY2j7.css +1 -0
  7. package/template/dist/assets/index-CnYqArKN.js +8741 -0
  8. package/template/dist/assets/sia_bg-BTOHUC1A.wasm +0 -0
  9. package/template/dist/assets/slab-download-worker-DhW6ZBJs.js +2 -0
  10. package/template/dist/assets/slab-upload-worker-B2uSB2iY.js +2 -0
  11. package/template/dist/index.html +13 -0
  12. package/template/e2e/smoke.spec.ts +20 -0
  13. package/template/index.html +0 -1
  14. package/template/package.json +2 -2
  15. package/template/playwright.config.ts +13 -0
  16. package/template/src/components/Navbar.tsx +3 -3
  17. package/template/src/components/auth/ApproveScreen.tsx +10 -13
  18. package/template/src/components/auth/AuthFlow.tsx +13 -10
  19. package/template/src/components/auth/ConnectScreen.tsx +2 -3
  20. package/template/src/components/auth/RecoveryScreen.tsx +7 -7
  21. package/template/src/components/upload/UploadZone.tsx +192 -74
  22. package/template/src/index.css +14 -4
  23. package/template/src/stores/auth.ts +6 -12
  24. package/template/test-results/.last-run.json +4 -0
  25. package/template/tsconfig.app.json +1 -1
  26. package/template/tsconfig.node.json +0 -1
  27. package/template/vite.config.ts +2 -3
  28. package/template/rust/README.md +0 -16
  29. package/template/rust/sia-sdk-rs/.changeset/added_cancel_function_to_cancel_inflight_packed_uploads.md +0 -6
  30. package/template/rust/sia-sdk-rs/.changeset/check_if_we_have_enough_hosts_prior_to_encoding_in_upload_slabs.md +0 -16
  31. package/template/rust/sia-sdk-rs/.changeset/fix_slab_length_in_packed_object.md +0 -5
  32. package/template/rust/sia-sdk-rs/.changeset/fix_upload_racing_race_conditon.md +0 -13
  33. package/template/rust/sia-sdk-rs/.changeset/improved_parallelism_of_packed_uploads.md +0 -5
  34. package/template/rust/sia-sdk-rs/.changeset/progress_callback_will_now_be_called_as_expected_for_packed_uploads.md +0 -5
  35. package/template/rust/sia-sdk-rs/.github/dependabot.yml +0 -10
  36. package/template/rust/sia-sdk-rs/.github/workflows/main.yml +0 -36
  37. package/template/rust/sia-sdk-rs/.github/workflows/prepare-release.yml +0 -34
  38. package/template/rust/sia-sdk-rs/.github/workflows/release.yml +0 -30
  39. package/template/rust/sia-sdk-rs/.rustfmt.toml +0 -4
  40. package/template/rust/sia-sdk-rs/Cargo.lock +0 -4127
  41. package/template/rust/sia-sdk-rs/Cargo.toml +0 -3
  42. package/template/rust/sia-sdk-rs/LICENSE +0 -21
  43. package/template/rust/sia-sdk-rs/README.md +0 -30
  44. package/template/rust/sia-sdk-rs/indexd/CHANGELOG.md +0 -79
  45. package/template/rust/sia-sdk-rs/indexd/Cargo.toml +0 -79
  46. package/template/rust/sia-sdk-rs/indexd/benches/upload.rs +0 -258
  47. package/template/rust/sia-sdk-rs/indexd/src/app_client.rs +0 -1710
  48. package/template/rust/sia-sdk-rs/indexd/src/builder.rs +0 -354
  49. package/template/rust/sia-sdk-rs/indexd/src/download.rs +0 -379
  50. package/template/rust/sia-sdk-rs/indexd/src/hosts.rs +0 -659
  51. package/template/rust/sia-sdk-rs/indexd/src/lib.rs +0 -827
  52. package/template/rust/sia-sdk-rs/indexd/src/mock.rs +0 -162
  53. package/template/rust/sia-sdk-rs/indexd/src/object_encryption.rs +0 -125
  54. package/template/rust/sia-sdk-rs/indexd/src/quic.rs +0 -575
  55. package/template/rust/sia-sdk-rs/indexd/src/rhp4.rs +0 -52
  56. package/template/rust/sia-sdk-rs/indexd/src/slabs.rs +0 -497
  57. package/template/rust/sia-sdk-rs/indexd/src/upload.rs +0 -629
  58. package/template/rust/sia-sdk-rs/indexd/src/wasm_time.rs +0 -41
  59. package/template/rust/sia-sdk-rs/indexd/src/web_transport.rs +0 -398
  60. package/template/rust/sia-sdk-rs/indexd_ffi/CHANGELOG.md +0 -76
  61. package/template/rust/sia-sdk-rs/indexd_ffi/Cargo.toml +0 -47
  62. package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/README.md +0 -10
  63. package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/example.py +0 -130
  64. package/template/rust/sia-sdk-rs/indexd_ffi/src/bin/uniffi-bindgen.rs +0 -3
  65. package/template/rust/sia-sdk-rs/indexd_ffi/src/builder.rs +0 -377
  66. package/template/rust/sia-sdk-rs/indexd_ffi/src/io.rs +0 -155
  67. package/template/rust/sia-sdk-rs/indexd_ffi/src/lib.rs +0 -1039
  68. package/template/rust/sia-sdk-rs/indexd_ffi/src/logging.rs +0 -58
  69. package/template/rust/sia-sdk-rs/indexd_ffi/src/tls.rs +0 -23
  70. package/template/rust/sia-sdk-rs/indexd_wasm/Cargo.toml +0 -33
  71. package/template/rust/sia-sdk-rs/indexd_wasm/src/lib.rs +0 -818
  72. package/template/rust/sia-sdk-rs/knope.toml +0 -54
  73. package/template/rust/sia-sdk-rs/sia_derive/CHANGELOG.md +0 -38
  74. package/template/rust/sia-sdk-rs/sia_derive/Cargo.toml +0 -19
  75. package/template/rust/sia-sdk-rs/sia_derive/src/lib.rs +0 -278
  76. package/template/rust/sia-sdk-rs/sia_sdk/CHANGELOG.md +0 -91
  77. package/template/rust/sia-sdk-rs/sia_sdk/Cargo.toml +0 -59
  78. package/template/rust/sia-sdk-rs/sia_sdk/benches/merkle_root.rs +0 -12
  79. package/template/rust/sia-sdk-rs/sia_sdk/src/blake2.rs +0 -22
  80. package/template/rust/sia-sdk-rs/sia_sdk/src/consensus.rs +0 -767
  81. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v1.rs +0 -257
  82. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v2.rs +0 -291
  83. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding.rs +0 -26
  84. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async/v2.rs +0 -367
  85. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async.rs +0 -6
  86. package/template/rust/sia-sdk-rs/sia_sdk/src/encryption.rs +0 -303
  87. package/template/rust/sia-sdk-rs/sia_sdk/src/erasure_coding.rs +0 -347
  88. package/template/rust/sia-sdk-rs/sia_sdk/src/lib.rs +0 -15
  89. package/template/rust/sia-sdk-rs/sia_sdk/src/macros.rs +0 -435
  90. package/template/rust/sia-sdk-rs/sia_sdk/src/merkle.rs +0 -112
  91. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/merkle.rs +0 -357
  92. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/rpc.rs +0 -1507
  93. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/types.rs +0 -146
  94. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp.rs +0 -7
  95. package/template/rust/sia-sdk-rs/sia_sdk/src/seed.rs +0 -278
  96. package/template/rust/sia-sdk-rs/sia_sdk/src/signing.rs +0 -236
  97. package/template/rust/sia-sdk-rs/sia_sdk/src/types/common.rs +0 -677
  98. package/template/rust/sia-sdk-rs/sia_sdk/src/types/currency.rs +0 -450
  99. package/template/rust/sia-sdk-rs/sia_sdk/src/types/specifier.rs +0 -110
  100. package/template/rust/sia-sdk-rs/sia_sdk/src/types/spendpolicy.rs +0 -778
  101. package/template/rust/sia-sdk-rs/sia_sdk/src/types/utils.rs +0 -117
  102. package/template/rust/sia-sdk-rs/sia_sdk/src/types/v1.rs +0 -1737
  103. package/template/rust/sia-sdk-rs/sia_sdk/src/types/v2.rs +0 -1726
  104. package/template/rust/sia-sdk-rs/sia_sdk/src/types/work.rs +0 -59
  105. package/template/rust/sia-sdk-rs/sia_sdk/src/types.rs +0 -16
  106. package/template/scripts/setup-rust.js +0 -29
  107. package/template/src/lib/format.ts +0 -35
  108. package/template/src/lib/hex.ts +0 -13
  109. package/template/src/lib/sdk.ts +0 -25
  110. package/template/src/lib/wasm-env.ts +0 -5
  111. package/template/wasm/indexd_wasm/indexd_wasm.d.ts +0 -309
  112. package/template/wasm/indexd_wasm/indexd_wasm.js +0 -1507
  113. package/template/wasm/indexd_wasm/indexd_wasm_bg.wasm +0 -0
  114. package/template/wasm/indexd_wasm/package.json +0 -31
@@ -1,257 +0,0 @@
1
- use super::{Error, Result};
2
- use std::io::{Read, Write};
3
-
4
- pub trait V1SiaEncodable {
5
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()>;
6
- }
7
-
8
- pub trait V1SiaDecodable: Sized {
9
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self>;
10
- }
11
-
12
- impl V1SiaEncodable for u8 {
13
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
14
- w.write_all(&[*self])?;
15
- Ok(())
16
- }
17
- }
18
-
19
- impl V1SiaDecodable for u8 {
20
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self> {
21
- let mut buf = [0; 1];
22
- r.read_exact(&mut buf)?;
23
- Ok(buf[0])
24
- }
25
- }
26
-
27
- impl V1SiaEncodable for bool {
28
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
29
- (*self as u8).encode_v1(w)
30
- }
31
- }
32
-
33
- impl V1SiaDecodable for bool {
34
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self> {
35
- let v = u8::decode_v1(r)?;
36
- match v {
37
- 0 => Ok(false),
38
- 1 => Ok(true),
39
- _ => Err(Error::InvalidValue("requires 0 or 1".into())),
40
- }
41
- }
42
- }
43
-
44
- impl<T: V1SiaEncodable> V1SiaEncodable for [T] {
45
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
46
- self.len().encode_v1(w)?;
47
- for item in self {
48
- item.encode_v1(w)?;
49
- }
50
- Ok(())
51
- }
52
- }
53
-
54
- impl<T: V1SiaEncodable> V1SiaEncodable for Option<T> {
55
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
56
- match self {
57
- Some(v) => {
58
- true.encode_v1(w)?;
59
- v.encode_v1(w)
60
- }
61
- None => false.encode_v1(w),
62
- }
63
- }
64
- }
65
-
66
- impl<T: V1SiaDecodable> V1SiaDecodable for Option<T> {
67
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self> {
68
- let has_value = bool::decode_v1(r)?;
69
- if has_value {
70
- Ok(Some(T::decode_v1(r)?))
71
- } else {
72
- Ok(None)
73
- }
74
- }
75
- }
76
-
77
- macro_rules! impl_sia_numeric {
78
- ($($t:ty),*) => {
79
- $(
80
- impl V1SiaEncodable for $t {
81
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
82
- w.write_all(&(*self as u64).to_le_bytes())?;
83
- Ok(())
84
- }
85
- }
86
-
87
- impl V1SiaDecodable for $t {
88
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self> {
89
- let mut buf = [0u8; 8];
90
- r.read_exact(&mut buf)?;
91
- Ok(u64::from_le_bytes(buf) as Self)
92
- }
93
- }
94
- )*
95
- }
96
- }
97
-
98
- impl_sia_numeric!(u16, u32, usize, i16, i32, i64, u64);
99
-
100
- impl<T> V1SiaEncodable for Vec<T>
101
- where
102
- T: V1SiaEncodable,
103
- {
104
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
105
- self.len().encode_v1(w)?;
106
- for item in self {
107
- item.encode_v1(w)?;
108
- }
109
- Ok(())
110
- }
111
- }
112
-
113
- impl<T> V1SiaDecodable for Vec<T>
114
- where
115
- T: V1SiaDecodable,
116
- {
117
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self> {
118
- let mut vec = Vec::new();
119
- // note: the vec is not pre-allocated
120
- // to prevent abuse by sending a large len
121
- for _ in 0..usize::decode_v1(r)? {
122
- vec.push(T::decode_v1(r)?);
123
- }
124
- Ok(vec)
125
- }
126
- }
127
-
128
- impl V1SiaEncodable for String {
129
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
130
- self.as_bytes().encode_v1(w)
131
- }
132
- }
133
-
134
- impl V1SiaDecodable for String {
135
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self> {
136
- let buf = Vec::<u8>::decode_v1(r)?;
137
- String::from_utf8(buf).map_err(|e| Error::InvalidValue(e.to_string()))
138
- }
139
- }
140
-
141
- impl<const N: usize> V1SiaEncodable for [u8; N] {
142
- fn encode_v1<W: Write>(&self, w: &mut W) -> Result<()> {
143
- w.write_all(self)?;
144
- Ok(())
145
- }
146
- }
147
-
148
- impl<const N: usize> V1SiaDecodable for [u8; N] {
149
- fn decode_v1<R: Read>(r: &mut R) -> Result<Self> {
150
- let mut arr = [0u8; N];
151
- r.read_exact(&mut arr)?;
152
- Ok(arr)
153
- }
154
- }
155
-
156
- #[cfg(test)]
157
- mod tests {
158
- use super::*;
159
-
160
- fn test_roundtrip<T: V1SiaEncodable + V1SiaDecodable + std::fmt::Debug + PartialEq>(
161
- value: T,
162
- expected_bytes: Vec<u8>,
163
- ) {
164
- let mut encoded_bytes = Vec::new();
165
- value
166
- .encode_v1(&mut encoded_bytes)
167
- .unwrap_or_else(|e| panic!("failed to encode: {e:?}"));
168
-
169
- assert_eq!(
170
- encoded_bytes, expected_bytes,
171
- "encoding mismatch for {value:?}"
172
- );
173
-
174
- let mut bytes = &expected_bytes[..];
175
- let decoded =
176
- T::decode_v1(&mut bytes).unwrap_or_else(|e| panic!("failed to decode: {e:?}"));
177
- assert_eq!(decoded, value, "decoding mismatch for {value:?}");
178
-
179
- assert_eq!(bytes.len(), 0, "leftover bytes for {value:?}");
180
- }
181
-
182
- #[test]
183
- fn test_numerics() {
184
- test_roundtrip(1u8, vec![1]);
185
- test_roundtrip(2u16, vec![2, 0, 0, 0, 0, 0, 0, 0]);
186
- test_roundtrip(3u32, vec![3, 0, 0, 0, 0, 0, 0, 0]);
187
- test_roundtrip(4u64, vec![4, 0, 0, 0, 0, 0, 0, 0]);
188
- test_roundtrip(5usize, vec![5, 0, 0, 0, 0, 0, 0, 0]);
189
- test_roundtrip(-1i16, vec![255, 255, 255, 255, 255, 255, 255, 255]);
190
- test_roundtrip(-2i32, vec![254, 255, 255, 255, 255, 255, 255, 255]);
191
- test_roundtrip(-3i64, vec![253, 255, 255, 255, 255, 255, 255, 255]);
192
- }
193
-
194
- #[test]
195
- fn test_strings() {
196
- test_roundtrip(
197
- "hello".to_string(),
198
- vec![
199
- 5, 0, 0, 0, 0, 0, 0, 0, // length prefix
200
- 104, 101, 108, 108, 111, // "hello"
201
- ],
202
- );
203
- test_roundtrip(
204
- "".to_string(),
205
- vec![0, 0, 0, 0, 0, 0, 0, 0], // empty string length
206
- );
207
- }
208
-
209
- #[test]
210
- fn test_fixed_arrays() {
211
- test_roundtrip([1u8, 2u8, 3u8], vec![1, 2, 3]);
212
- test_roundtrip([0u8; 4], vec![0, 0, 0, 0]);
213
- }
214
-
215
- #[test]
216
- fn test_vectors() {
217
- test_roundtrip(
218
- vec![1u8, 2u8, 3u8],
219
- vec![
220
- 3, 0, 0, 0, 0, 0, 0, 0, // length prefix
221
- 1, 2, 3, // values
222
- ],
223
- );
224
- test_roundtrip(
225
- vec![100u64, 200u64],
226
- vec![
227
- 2, 0, 0, 0, 0, 0, 0, 0, // length prefix
228
- 100, 0, 0, 0, 0, 0, 0, 0, // 100u64
229
- 200, 0, 0, 0, 0, 0, 0, 0, // 200u64
230
- ],
231
- );
232
- test_roundtrip(
233
- vec!["a".to_string(), "bc".to_string()],
234
- vec![
235
- 2, 0, 0, 0, 0, 0, 0, 0, // vector length
236
- 1, 0, 0, 0, 0, 0, 0, 0, // first string length
237
- 97, // "a"
238
- 2, 0, 0, 0, 0, 0, 0, 0, // second string length
239
- 98, 99, // "bc"
240
- ],
241
- );
242
- }
243
-
244
- #[test]
245
- fn test_nested() {
246
- test_roundtrip(
247
- vec![vec![1u8, 2u8], vec![3u8, 4u8]],
248
- vec![
249
- 2, 0, 0, 0, 0, 0, 0, 0, // outer vec length
250
- 2, 0, 0, 0, 0, 0, 0, 0, // first inner vec length
251
- 1, 2, // first inner vec contents
252
- 2, 0, 0, 0, 0, 0, 0, 0, // second inner vec length
253
- 3, 4, // second inner vec contents
254
- ],
255
- );
256
- }
257
- }
@@ -1,291 +0,0 @@
1
- use chrono::{DateTime, Duration, Utc};
2
-
3
- use super::{Error, Result};
4
- use std::io::{Read, Write};
5
-
6
- pub trait SiaEncodable {
7
- fn encode<W: Write>(&self, w: &mut W) -> Result<()>;
8
- }
9
-
10
- pub trait SiaDecodable: Sized {
11
- fn decode<R: Read>(r: &mut R) -> Result<Self>;
12
- }
13
-
14
- impl SiaEncodable for u8 {
15
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
16
- w.write_all(&[*self])?;
17
- Ok(())
18
- }
19
- }
20
-
21
- impl SiaDecodable for u8 {
22
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
23
- let mut buf = [0; 1];
24
- r.read_exact(&mut buf)?;
25
- Ok(buf[0])
26
- }
27
- }
28
-
29
- impl SiaEncodable for bool {
30
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
31
- (*self as u8).encode(w)
32
- }
33
- }
34
-
35
- impl SiaDecodable for bool {
36
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
37
- let v = u8::decode(r)?;
38
- match v {
39
- 0 => Ok(false),
40
- 1 => Ok(true),
41
- _ => Err(Error::InvalidValue("requires 0 or 1".into())),
42
- }
43
- }
44
- }
45
-
46
- impl SiaEncodable for DateTime<Utc> {
47
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
48
- self.timestamp().encode(w)
49
- }
50
- }
51
-
52
- impl SiaDecodable for DateTime<Utc> {
53
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
54
- let timestamp = i64::decode(r)?;
55
- DateTime::from_timestamp_secs(timestamp)
56
- .ok_or_else(|| Error::InvalidValue(format!("invalid timestamp: {timestamp}")))
57
- }
58
- }
59
-
60
- impl SiaEncodable for Duration {
61
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
62
- self.num_nanoseconds()
63
- .ok_or_else(|| Error::InvalidValue("duration too large".into()))?
64
- .encode(w)
65
- }
66
- }
67
-
68
- impl SiaDecodable for Duration {
69
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
70
- let ns = u64::decode(r)?;
71
- if ns > i64::MAX as u64 {
72
- return Err(Error::InvalidValue(format!(
73
- "duration {ns} must be less than {}",
74
- i64::MAX
75
- )));
76
- }
77
- Ok(Duration::nanoseconds(ns as i64))
78
- }
79
- }
80
-
81
- impl<T: SiaEncodable> SiaEncodable for [T] {
82
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
83
- self.len().encode(w)?;
84
- for item in self {
85
- item.encode(w)?;
86
- }
87
- Ok(())
88
- }
89
- }
90
-
91
- impl<T: SiaEncodable> SiaEncodable for Option<T> {
92
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
93
- match self {
94
- Some(v) => {
95
- true.encode(w)?;
96
- v.encode(w)
97
- }
98
- None => false.encode(w),
99
- }
100
- }
101
- }
102
-
103
- impl<T: SiaDecodable> SiaDecodable for Option<T> {
104
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
105
- match bool::decode(r)? {
106
- true => Ok(Some(T::decode(r)?)),
107
- false => Ok(None),
108
- }
109
- }
110
- }
111
-
112
- macro_rules! impl_sia_numeric {
113
- ($($t:ty),*) => {
114
- $(
115
- impl SiaEncodable for $t {
116
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
117
- w.write_all(&(*self as u64).to_le_bytes())?;
118
- Ok(())
119
- }
120
- }
121
-
122
- impl SiaDecodable for $t {
123
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
124
- let mut buf = [0u8; 8];
125
- r.read_exact(&mut buf)?;
126
- Ok(u64::from_le_bytes(buf) as Self)
127
- }
128
- }
129
- )*
130
- }
131
- }
132
-
133
- impl_sia_numeric!(u16, u32, usize, i16, i32, i64, u64);
134
-
135
- impl<T> SiaEncodable for Vec<T>
136
- where
137
- T: SiaEncodable,
138
- {
139
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
140
- self.len().encode(w)?;
141
- for item in self {
142
- item.encode(w)?;
143
- }
144
- Ok(())
145
- }
146
- }
147
-
148
- impl<T> SiaDecodable for Vec<T>
149
- where
150
- T: SiaDecodable,
151
- {
152
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
153
- let mut vec = Vec::new();
154
- // note: the vec is not pre-allocated
155
- // to prevent abuse by sending a large len
156
- for _ in 0..usize::decode(r)? {
157
- vec.push(T::decode(r)?);
158
- }
159
- Ok(vec)
160
- }
161
- }
162
-
163
- impl SiaEncodable for String {
164
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
165
- self.as_bytes().encode(w)
166
- }
167
- }
168
-
169
- impl SiaDecodable for String {
170
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
171
- let buf = Vec::<u8>::decode(r)?;
172
- String::from_utf8(buf).map_err(|e| Error::InvalidValue(e.to_string()))
173
- }
174
- }
175
-
176
- impl<const N: usize> SiaEncodable for [u8; N] {
177
- fn encode<W: Write>(&self, w: &mut W) -> Result<()> {
178
- w.write_all(self)?;
179
- Ok(())
180
- }
181
- }
182
-
183
- impl<const N: usize> SiaDecodable for [u8; N] {
184
- fn decode<R: Read>(r: &mut R) -> Result<Self> {
185
- let mut arr = [0u8; N];
186
- r.read_exact(&mut arr)?;
187
- Ok(arr)
188
- }
189
- }
190
-
191
- #[cfg(test)]
192
- mod tests {
193
- use super::*;
194
-
195
- fn test_roundtrip<T: SiaEncodable + SiaDecodable + std::fmt::Debug + PartialEq>(
196
- value: T,
197
- expected_bytes: Vec<u8>,
198
- ) {
199
- let mut encoded_bytes = Vec::new();
200
- value
201
- .encode(&mut encoded_bytes)
202
- .unwrap_or_else(|e| panic!("failed to encode: {e:?}"));
203
-
204
- assert_eq!(
205
- encoded_bytes, expected_bytes,
206
- "encoding mismatch for {value:?}"
207
- );
208
-
209
- let mut bytes = &expected_bytes[..];
210
- let decoded = T::decode(&mut bytes).unwrap_or_else(|e| panic!("failed to decode: {e:?}"));
211
- assert_eq!(decoded, value, "decoding mismatch for {value:?}");
212
-
213
- assert_eq!(bytes.len(), 0, "leftover bytes for {value:?}");
214
- }
215
-
216
- #[test]
217
- fn test_numerics() {
218
- test_roundtrip(1u8, vec![1]);
219
- test_roundtrip(2u16, vec![2, 0, 0, 0, 0, 0, 0, 0]);
220
- test_roundtrip(3u32, vec![3, 0, 0, 0, 0, 0, 0, 0]);
221
- test_roundtrip(4u64, vec![4, 0, 0, 0, 0, 0, 0, 0]);
222
- test_roundtrip(5usize, vec![5, 0, 0, 0, 0, 0, 0, 0]);
223
- test_roundtrip(-1i16, vec![255, 255, 255, 255, 255, 255, 255, 255]);
224
- test_roundtrip(-2i32, vec![254, 255, 255, 255, 255, 255, 255, 255]);
225
- test_roundtrip(-3i64, vec![253, 255, 255, 255, 255, 255, 255, 255]);
226
- }
227
-
228
- #[test]
229
- fn test_strings() {
230
- test_roundtrip(
231
- "hello".to_string(),
232
- vec![
233
- 5, 0, 0, 0, 0, 0, 0, 0, // length prefix
234
- 104, 101, 108, 108, 111, // "hello"
235
- ],
236
- );
237
- test_roundtrip(
238
- "".to_string(),
239
- vec![0, 0, 0, 0, 0, 0, 0, 0], // empty string length
240
- );
241
- }
242
-
243
- #[test]
244
- fn test_fixed_arrays() {
245
- test_roundtrip([1u8, 2u8, 3u8], vec![1, 2, 3]);
246
- test_roundtrip([0u8; 4], vec![0, 0, 0, 0]);
247
- }
248
-
249
- #[test]
250
- fn test_vectors() {
251
- test_roundtrip(
252
- vec![1u8, 2u8, 3u8],
253
- vec![
254
- 3, 0, 0, 0, 0, 0, 0, 0, // length prefix
255
- 1, 2, 3, // values
256
- ],
257
- );
258
- test_roundtrip(
259
- vec![100u64, 200u64],
260
- vec![
261
- 2, 0, 0, 0, 0, 0, 0, 0, // length prefix
262
- 100, 0, 0, 0, 0, 0, 0, 0, // 100u64
263
- 200, 0, 0, 0, 0, 0, 0, 0, // 200u64
264
- ],
265
- );
266
- test_roundtrip(
267
- vec!["a".to_string(), "bc".to_string()],
268
- vec![
269
- 2, 0, 0, 0, 0, 0, 0, 0, // vector length
270
- 1, 0, 0, 0, 0, 0, 0, 0, // first string length
271
- 97, // "a"
272
- 2, 0, 0, 0, 0, 0, 0, 0, // second string length
273
- 98, 99, // "bc"
274
- ],
275
- );
276
- }
277
-
278
- #[test]
279
- fn test_nested() {
280
- test_roundtrip(
281
- vec![vec![1u8, 2u8], vec![3u8, 4u8]],
282
- vec![
283
- 2, 0, 0, 0, 0, 0, 0, 0, // outer vec length
284
- 2, 0, 0, 0, 0, 0, 0, 0, // first inner vec length
285
- 1, 2, // first inner vec contents
286
- 2, 0, 0, 0, 0, 0, 0, 0, // second inner vec length
287
- 3, 4, // second inner vec contents
288
- ],
289
- );
290
- }
291
- }
@@ -1,26 +0,0 @@
1
- use std::io;
2
-
3
- use thiserror::Error;
4
-
5
- mod v1;
6
- mod v2;
7
-
8
- #[derive(Debug, Error)]
9
- pub enum Error {
10
- #[error("IO error: {0}")]
11
- Io(#[from] io::Error),
12
- #[error("Invalid length")]
13
- InvalidLength(usize),
14
- #[error("Invalid value: {0}")]
15
- InvalidValue(String),
16
- #[error("Custom error: {0}")]
17
- Custom(String),
18
- }
19
-
20
- pub type Result<T> = std::result::Result<T, Error>;
21
-
22
- pub use sia_derive::{SiaDecode, SiaEncode};
23
- pub use v2::{SiaDecodable, SiaEncodable};
24
-
25
- pub use sia_derive::{V1SiaDecode, V1SiaEncode};
26
- pub use v1::{V1SiaDecodable, V1SiaEncodable};