use std::str::FromStr;
use std::fmt;
use a2kit_macro::{DiskStructError,DiskStruct};
use super::super::TextConversion;
#[derive(thiserror::Error,Debug)]
pub enum Error {
#[error("general")]
General,
#[error("read fault")]
ReadFault,
#[error("sector not found")]
SectorNotFound,
#[error("write fault")]
WriteFault,
#[error("write protect")]
WriteProtect,
#[error("invalid command line parameter")]
InvalidSwitch,
#[error("File allocation table bad")]
BadFAT,
#[error("file not found")]
FileNotFound,
#[error("duplicate file name")]
DuplicateFile,
#[error("insufficient disk space")]
DiskFull,
#[error("no room in directory")]
DirectoryFull,
#[error("directory not empty")]
DirectoryNotEmpty,
#[error("syntax")]
Syntax,
#[error("first cluster invalid")]
FirstClusterInvalid,
#[error("incorrect DOS version")]
IncorrectDOS
}
#[derive(PartialEq,Eq,Copy,Clone)]
pub enum Ptr {
Entry(usize),
Cluster(usize),
LogicalSector(usize)
}
impl Ptr {
pub fn unwrap(&self) -> usize {
match self {
Self::Entry(i) => *i,
Self::Cluster(i) => *i,
Self::LogicalSector(i) => *i
}
}
}
impl PartialOrd for Ptr {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match (self,other) {
(Self::Entry(x),Self::Entry(y)) => x.partial_cmp(y),
(Self::Cluster(x),Self::Cluster(y)) => x.partial_cmp(y),
(Self::LogicalSector(x),Self::LogicalSector(y)) => x.partial_cmp(y),
_ => None
}
}
}
impl Ord for Ptr {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.unwrap().cmp(&other.unwrap())
}
}
type TextConverter = crate::fs::cpm::types::TextConverter;
pub struct SequentialText {
pub text: Vec<u8>,
terminator: u8
}
impl FromStr for SequentialText {
type Err = std::fmt::Error;
fn from_str(s: &str) -> Result<Self,Self::Err> {
let encoder = TextConverter::new(vec![]);
if let Some(dat) = encoder.from_utf8(s) {
return Ok(Self {
text: dat.clone(),
terminator: 0x1a
});
}
Err(std::fmt::Error)
}
}
impl fmt::Display for SequentialText {
fn fmt(&self,f: &mut fmt::Formatter<'_>) -> fmt::Result {
let encoder = TextConverter::new(vec![]);
if let Some(ans) = encoder.to_utf8(&self.text) {
return write!(f,"{}",ans);
}
write!(f,"err")
}
}
impl DiskStruct for SequentialText {
fn new() -> Self {
Self {
text: Vec::new(),
terminator: 0x1a
}
}
fn from_bytes(dat: &[u8]) -> Result<Self,DiskStructError> {
Ok(Self {
text: match dat.split(|x| *x==0x1a).next() {
Some(v) => v.to_vec(),
_ => dat.to_vec()
},
terminator: 0x1a
})
}
fn to_bytes(&self) -> Vec<u8> {
let mut ans: Vec<u8> = Vec::new();
ans.append(&mut self.text.clone());
ans.push(self.terminator);
return ans;
}
fn update_from_bytes(&mut self,dat: &[u8]) -> Result<(),DiskStructError> {
let temp = SequentialText::from_bytes(&dat)?;
self.text = temp.text.clone();
self.terminator = 0x1a;
Ok(())
}
fn len(&self) -> usize {
self.text.len() + 1
}
}