use serde::{Deserialize, Serialize};
pub fn generate_unique_id() -> u64 {
let mut buf = [0u8; 8];
let val = if getrandom::getrandom(&mut buf).is_err() {
let now = web_time::SystemTime::now()
.duration_since(web_time::SystemTime::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0);
now as u64
} else {
u64::from_le_bytes(buf)
};
val & 0x001F_FFFF_FFFF_FFFF
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum RefType {
Relative,
Absolute,
}
impl std::fmt::Display for RefType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
RefType::Relative => write!(f, ""),
RefType::Absolute => write!(f, "$"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct CellRef {
pub row: usize,
pub col: usize,
pub row_ref_type: RefType,
pub col_ref_type: RefType,
}
impl std::fmt::Display for CellRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"CELL({}{}, {}{})",
self.row_ref_type, self.row, self.col_ref_type, self.col
)
}
}
impl CellRef {
pub fn new(row: usize, col: usize) -> CellRef {
Self {
row,
col,
row_ref_type: RefType::Relative,
col_ref_type: RefType::Relative,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Dependency {
Local(CellRef),
LocalColumn(usize),
Remote {
sheet: String,
cell: CellRef,
},
RemoteColumn {
sheet: String,
col: usize,
},
}
#[derive(Debug, Clone, Default)]
pub struct TextCellRef {
pub row: usize,
pub col: usize,
pub char_offset: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EvalError {
UnknownFunction(String),
}
impl std::error::Error for EvalError {}
impl std::fmt::Display for EvalError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EvalError::UnknownFunction(func) => write!(f, "{}", func),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EngineError {
EvalError(EvalError),
}
impl std::error::Error for EngineError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
EngineError::EvalError(err) => Some(err),
}
}
}
impl std::fmt::Display for EngineError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EngineError::EvalError(err) => write!(f, "{}", err),
}
}
}
impl From<EvalError> for EngineError {
fn from(err: EvalError) -> Self {
EngineError::EvalError(err)
}
}