taubyte_sdk/storage/
files.rs1use super::file::{File, VersionedFile};
2use super::{imports, Storage};
3use crate::errno::Error;
4
5impl Storage {
6 pub fn file(&self, file_name: &str) -> File {
7 File::new(self.id, file_name)
8 }
9
10 fn file_versioned(&self, file_name: &str, version: u32) -> VersionedFile {
11 VersionedFile::new(File::new(self.id, file_name), version)
12 }
13
14 fn list_files_size_unsafe(&self, size: *mut usize) -> Error {
15 #[allow(unused_unsafe)]
16 unsafe {
17 imports::storageListFilesSize(self.id, size)
18 }
19 }
20
21 fn list_files_unsafe(&self, files: *mut u8) -> Error {
22 #[allow(unused_unsafe)]
23 unsafe {
24 imports::storageListFiles(self.id, files)
25 }
26 }
27
28 pub fn list_files(&self) -> Result<Vec<VersionedFile>, Box<dyn std::error::Error>> {
29 let mut size: usize = 0;
30 let err = self.list_files_size_unsafe(&mut size);
31 if err.is_err() {
32 return Err(format!("Failed storage list file size with {}", err).into());
33 }
34
35 let mut buf = vec![0_u8; size];
36 let err = self.list_files_unsafe(&mut buf[0]);
37 if err.is_err() {
38 return Err(format!("Failed storage list files with {}", err).into());
39 }
40
41 let mut files: Vec<VersionedFile> = Vec::new();
42
43 let values = String::from_utf8(buf)?;
44 let values_split = values.split('/');
45 let values: Vec<&str> = values_split.collect();
46 for (idx, value) in values.iter().enumerate() {
47 if *value == "file" && values[idx + 1] != "file" {
48 let version = values[idx + 2].trim_matches('\x00');
49 let version = version.parse::<u32>()?;
50 files.push(self.file_versioned(values[idx + 1], version));
51 }
52 continue;
53 }
54
55 Ok(files)
56 }
57}
58
59#[cfg(test)]
60pub mod test {
61 use crate::storage::file::{File, VersionedFile};
62 use crate::storage::new::test as new_test;
63 use crate::storage::Storage;
64
65 pub static FILE_STR: &str = "file/file1/1/file/file2/1/file/file3/2";
66
67 #[test]
68 fn list_files() {
69 let storage = Storage::new(new_test::STORAGE_NAME).unwrap_or_else(|err| {
70 panic!("{}", err);
71 });
72
73 let files = storage.list_files().unwrap_or_else(|err| {
74 panic!("{}", err);
75 });
76
77 let expected_files = vec![
78 VersionedFile::new(File::new(new_test::STORAGE_ID, "file1"), 1),
79 VersionedFile::new(File::new(new_test::STORAGE_ID, "file2"), 1),
80 VersionedFile::new(File::new(new_test::STORAGE_ID, "file3"), 2),
81 ];
82
83 assert_eq!(files, expected_files);
84 }
85}
86
87#[cfg(test)]
88#[allow(non_snake_case)]
89pub mod mock {
90 use crate::{
91 errno::{Errno, Error},
92 storage::new::test as new_test,
93 utils::test as utils,
94 };
95
96 pub fn storageListFilesSize(storage_id: u32, size: *mut usize) -> Error {
97 use super::test;
98
99 if storage_id != new_test::STORAGE_ID {
100 Errno::ErrorCap.error()
101 } else {
102 utils::write_usize(size, test::FILE_STR.len());
103 Errno::ErrorNone.error()
104 }
105 }
106
107 pub fn storageListFiles(storage_id: u32, files: *mut u8) -> Error {
108 use super::test;
109
110 if storage_id != new_test::STORAGE_ID {
111 Errno::ErrorCap.error()
112 } else {
113 utils::write_string(files, test::FILE_STR);
114 Errno::ErrorNone.error()
115 }
116 }
117}