a2kit/lang/
disk_server.rs1use crate::commands::{ItemType,CommandError};
6use crate::fs::DiskFS;
7use crate::img::tracks::DiskFormat;
8use crate::{STDRESULT,DYNERR};
9
10pub struct DiskServer {
11 path_to_img: String,
12 disk: Option<Box<dyn DiskFS>>
13}
14
15pub struct SimpleFileImage {
16 pub file_system: String,
17 pub fs_type: Vec<u8>,
18 pub load_addr: usize,
19 pub data: Vec<u8>
20}
21
22pub enum SelectionResult {
23 Directory(Vec<String>),
24 FileData(SimpleFileImage)
25}
26
27impl DiskServer {
28 pub fn new() -> Self {
29 Self {
30 path_to_img: "".to_string(),
31 disk: None
32 }
33 }
34 pub fn mount(&mut self,path_to_img: &str,maybe_white_list: &Option<Vec<String>>,maybe_fmt: Option<&DiskFormat>) -> STDRESULT {
38 match crate::create_fs_from_file(path_to_img,maybe_fmt) {
39 Ok(mut disk) => {
40 let stat = disk.stat()?;
41 match maybe_white_list {
42 Some(white_list) => {
43 if white_list.contains(&stat.fs_name) {
44 self.disk = Some(disk);
45 self.path_to_img = path_to_img.to_string();
46 Ok(())
47 } else {
48 Err(Box::new(CommandError::UnsupportedFormat))
49 }
50 },
51 None => {
52 self.disk = Some(disk);
53 self.path_to_img = path_to_img.to_string();
54 Ok(())
55 }
56 }
57 },
58 Err(e) => Err(e)
59 }
60 }
61 fn evaluate_selection(&mut self,path: &str,maybe_white_list: Option<Vec<String>>) -> Result<SelectionResult,DYNERR> {
62 if let Some(disk) = self.disk.as_mut() {
63 if let Ok(full_cat) = disk.catalog_to_vec(path) {
64 if maybe_white_list.is_none() {
65 return Ok(SelectionResult::Directory(full_cat));
66 }
67 let mut filtered_cat = Vec::new();
68 let mut white_list = maybe_white_list.to_owned().unwrap();
69 if !white_list.contains(&"DIR".to_string()) {
70 white_list.push("DIR".to_string());
71 }
72 for row in full_cat {
73 for typ in &white_list {
74 if row.starts_with(&typ.to_uppercase()) {
75 filtered_cat.push(row);
76 break;
77 }
78 }
79 }
80 return Ok(SelectionResult::Directory(filtered_cat));
81 }
82 return match disk.get(path) {
83 Ok(fimg) => Ok(SelectionResult::FileData(SimpleFileImage {
84 file_system: fimg.file_system.clone(),
85 fs_type: fimg.fs_type.clone(),
86 load_addr: fimg.get_load_address(),
87 data: match fimg.unpack() {
88 Ok(result) => match result {
89 crate::fs::UnpackedData::Binary(dat) => dat,
90 crate::fs::UnpackedData::Text(txt) => txt.as_bytes().to_vec(),
91 _ => return Err(Box::new(CommandError::UnsupportedFormat))
92 },
93 Err(e) => return Err(e)
94 }
95 })),
96 Err(e) => Err(e)
97 }
98 }
99 return Err(Box::new(CommandError::InvalidCommand));
100 }
101 pub fn handle_selection(&mut self,args: &Vec<serde_json::Value>) -> Result<SelectionResult,DYNERR> {
107 if args.len()!=2 {
108 return Err(Box::new(CommandError::UnknownFormat));
109 }
110 let maybe_img_path = serde_json::from_value::<String>(args[0].clone());
111 let maybe_white_list = serde_json::from_value::<Vec<String>>(args[1].clone());
112 match (maybe_img_path,maybe_white_list) {
113 (Ok(path),Ok(white_list)) => self.evaluate_selection(&path, Some(white_list)),
114 (Ok(path),Err(_)) => self.evaluate_selection(&path,None),
115 _ => Err(Box::new(CommandError::UnknownFormat))
116 }
117 }
118 pub fn write(&mut self,path: &str,dat: &[u8],typ: ItemType) -> STDRESULT {
121 match self.disk.as_mut() { Some(disk) => {
122 let mut fimg = disk.new_fimg(None, true, path)?;
123 match typ {
124 ItemType::IntegerTokens | ItemType::ApplesoftTokens => fimg.pack_tok(dat,typ,None)?,
125 ItemType::MerlinTokens => fimg.pack_raw(dat)?,
126 ItemType::Text => fimg.pack_raw(dat)?,
127 _ => return Err(Box::new(CommandError::UnsupportedFormat))
128 };
129 disk.put(&fimg)?;
130 crate::save_img(disk, &self.path_to_img)?;
131 Ok(())
132 } _ => {
133 Err(Box::new(CommandError::InvalidCommand))
134 }}
135 }
136 pub fn delete(&mut self,path: &str) -> STDRESULT {
140 match self.disk.as_mut() { Some(disk) => {
141 disk.delete(path)
142 } _ => {
143 Err(Box::new(CommandError::InvalidCommand))
144 }}
145 }
146}