summaryrefslogtreecommitdiff
path: root/src/devices/file_device.rs
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-03-25 12:46:49 +1300
committerBen Bridle <ben@derelict.engineering>2025-03-25 12:48:49 +1300
commitab84ad75629b0a4124221023ca91411d2cd62a32 (patch)
tree0c333f06bec5270084aaec71cf173c798420207b /src/devices/file_device.rs
parent07ae3438917fd854a46924a410f6890cd0651f1b (diff)
downloadbedrock-pc-ab84ad75629b0a4124221023ca91411d2cd62a32.zip
Restructure program
This commit also includes changes to devices according to the latest devices specification, in particular the math and system devices.
Diffstat (limited to 'src/devices/file_device.rs')
-rw-r--r--src/devices/file_device.rs155
1 files changed, 95 insertions, 60 deletions
diff --git a/src/devices/file_device.rs b/src/devices/file_device.rs
index 61966b1..f8d8fa0 100644
--- a/src/devices/file_device.rs
+++ b/src/devices/file_device.rs
@@ -1,20 +1,4 @@
-mod bedrock_file_path;
-mod bedrock_path_buffer;
-mod buffered_file;
-mod directory_listing;
-mod entry;
-mod operations;
-
-use buffered_file::BufferedFile;
-use bedrock_file_path::BedrockFilePath;
-use bedrock_path_buffer::BedrockPathBuffer;
-use directory_listing::DirectoryListing;
-use entry::{Entry, EntryType};
-use operations::{create_file, move_entry, delete_entry};
-
-use bedrock_core::*;
-
-use std::path::{Component, Path, PathBuf};
+use crate::*;
pub struct FileDevice {
@@ -39,6 +23,59 @@ pub struct FileDevice {
pub enable_delete: bool,
}
+
+impl Device for FileDevice {
+ fn read(&mut self, port: u8) -> u8 {
+ match port {
+ 0x0 => read_b!(self.entry.is_some()),
+ 0x1 => read_b!(self.success),
+ 0x2 => self.path_buffer.read(),
+ 0x3 => read_b!(self.entry_type()),
+ 0x4 => self.read_byte(),
+ 0x5 => self.read_byte(),
+ 0x6 => self.read_child_path(),
+ 0x7 => read_b!(self.child_type()),
+ 0x8 => read_hh!(self.pointer()),
+ 0x9 => read_hl!(self.pointer()),
+ 0xa => read_lh!(self.pointer()),
+ 0xb => read_ll!(self.pointer()),
+ 0xc => read_hh!(self.length()),
+ 0xd => read_hl!(self.length()),
+ 0xe => read_lh!(self.length()),
+ 0xf => read_ll!(self.length()),
+ _ => unreachable!(),
+ }
+ }
+
+ fn write(&mut self, port: u8, value: u8) -> Option<Signal> {
+ match port {
+ 0x0 => self.write_to_entry_port(value),
+ 0x1 => self.write_to_action_port(value),
+ 0x2 => self.path_buffer.set_pointer(value),
+ 0x3 => self.ascend_to_parent(),
+ 0x4 => self.write_byte(value),
+ 0x5 => self.write_byte(value),
+ 0x6 => self.set_child_path(value),
+ 0x7 => self.descend_to_child(),
+ 0x8 => write_hh!(self.pointer_write, value),
+ 0x9 => write_hl!(self.pointer_write, value),
+ 0xa => write_lh!(self.pointer_write, value),
+ 0xb => {write_ll!(self.pointer_write, value); self.commit_pointer()},
+ 0xc => write_hh!(self.length_write, value),
+ 0xd => write_hl!(self.length_write, value),
+ 0xe => write_lh!(self.length_write, value),
+ 0xf => {write_ll!(self.length_write, value); self.commit_length()},
+ _ => unreachable!(),
+ };
+ return None;
+ }
+
+ fn wake(&mut self) -> bool {
+ false
+ }
+}
+
+
impl FileDevice {
pub fn new() -> Self {
#[cfg(target_family = "unix")]
@@ -279,59 +316,57 @@ impl FileDevice {
}
}
+
impl Drop for FileDevice {
fn drop(&mut self) {
self.flush();
}
}
-impl Device for FileDevice {
- fn read(&mut self, port: u8) -> u8 {
- match port {
- 0x0 => read_b!(self.entry.is_some()),
- 0x1 => read_b!(self.success),
- 0x2 => self.path_buffer.read(),
- 0x3 => read_b!(self.entry_type()),
- 0x4 => self.read_byte(),
- 0x5 => self.read_byte(),
- 0x6 => self.read_child_path(),
- 0x7 => read_b!(self.child_type()),
- 0x8 => read_hh!(self.pointer()),
- 0x9 => read_hl!(self.pointer()),
- 0xa => read_lh!(self.pointer()),
- 0xb => read_ll!(self.pointer()),
- 0xc => read_hh!(self.length()),
- 0xd => read_hl!(self.length()),
- 0xe => read_lh!(self.length()),
- 0xf => read_ll!(self.length()),
- _ => unreachable!(),
+
+/// Create a new file if it doesn't already exist, returning true if successful.
+pub fn create_file(destination: &Path) -> bool {
+ if entry_exists(destination) {
+ false
+ } else {
+ if let Some(parent_path) = destination.parent() {
+ let _ = std::fs::create_dir_all(parent_path);
}
+ std::fs::OpenOptions::new().write(true).create_new(true)
+ .open(destination).is_ok()
}
+}
- fn write(&mut self, port: u8, value: u8) -> Option<Signal> {
- match port {
- 0x0 => self.write_to_entry_port(value),
- 0x1 => self.write_to_action_port(value),
- 0x2 => self.path_buffer.set_pointer(value),
- 0x3 => self.ascend_to_parent(),
- 0x4 => self.write_byte(value),
- 0x5 => self.write_byte(value),
- 0x6 => self.set_child_path(value),
- 0x7 => self.descend_to_child(),
- 0x8 => write_hh!(self.pointer_write, value),
- 0x9 => write_hl!(self.pointer_write, value),
- 0xa => write_lh!(self.pointer_write, value),
- 0xb => {write_ll!(self.pointer_write, value); self.commit_pointer()},
- 0xc => write_hh!(self.length_write, value),
- 0xd => write_hl!(self.length_write, value),
- 0xe => write_lh!(self.length_write, value),
- 0xf => {write_ll!(self.length_write, value); self.commit_length()},
- _ => unreachable!(),
- };
- return None;
+/// Move an entry from one location to another, returning true if successful.
+pub fn move_entry(source: &Path, destination: &Path) -> bool {
+ if !entry_exists(source) || entry_exists(destination) {
+ return false;
}
+ std::fs::rename(source, destination).is_ok()
+}
- fn wake(&mut self) -> bool {
- false
+/// Delete an entry, returning true if successful.
+pub fn delete_entry(source: &Path) -> bool {
+ use std::fs::{remove_file, remove_dir_all};
+ use std::io::ErrorKind;
+
+ match remove_file(source) {
+ Ok(_) => true,
+ Err(error) => match error.kind() {
+ ErrorKind::NotFound => true,
+ ErrorKind::IsADirectory => match remove_dir_all(source) {
+ Ok(_) => true,
+ Err(error) => match error.kind() {
+ ErrorKind::NotFound => true,
+ _ => false,
+ }
+ }
+ _ => false,
+ }
}
}
+
+/// Returns true if an entry already exists at the given path.
+fn entry_exists(source: &Path) -> bool {
+ std::fs::metadata(source).is_ok()
+}