Add code
This commit is contained in:
parent
ee280d63ac
commit
e183fb64e2
6 changed files with 374 additions and 0 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
use nix
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
.direnv/
|
||||
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "polyparse"
|
||||
version = "0.1.0"
|
||||
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "polyparse"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
9
shell.nix
Normal file
9
shell.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
cargo
|
||||
helix
|
||||
rust-analyzer
|
||||
cargo-watch
|
||||
];
|
||||
}
|
||||
349
src/lib.rs
Normal file
349
src/lib.rs
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
#[derive(Debug)]
|
||||
pub enum NapAmount {
|
||||
N(u8),
|
||||
X,
|
||||
AMAYL,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ScheduleKind {
|
||||
Siesta,
|
||||
Everyman(NapAmount),
|
||||
DualCore(NapAmount),
|
||||
Thinkphasic(NapAmount),
|
||||
TriCore(NapAmount),
|
||||
QuadCore(NapAmount),
|
||||
CAMAYL,
|
||||
Uberman(NapAmount),
|
||||
Uberman30(NapAmount),
|
||||
Bimaxion,
|
||||
Trimaxion,
|
||||
Zoidberg(NapAmount),
|
||||
}
|
||||
|
||||
impl ScheduleKind {
|
||||
pub fn from_ident(s: &str) -> Option<ScheduleKind> {
|
||||
use NapAmount::*;
|
||||
use ScheduleKind::*;
|
||||
let s_orig = s.to_uppercase();
|
||||
let (s, rest) = s_orig
|
||||
.split_once(|c: char| c.is_numeric() || c == '-')
|
||||
.unwrap_or((&s_orig, ""));
|
||||
if s.starts_with("M") {
|
||||
return Some(Everyman(Self::detect_naps(&s_orig).unwrap_or(N(0))));
|
||||
}
|
||||
if s.starts_with("BI") {
|
||||
if s.contains("MA") {
|
||||
return Some(Bimaxion);
|
||||
}
|
||||
if s.contains("X") || rest.starts_with("X") {
|
||||
return Some(Everyman(X));
|
||||
}
|
||||
return Some(Everyman(N(1)));
|
||||
}
|
||||
if s.starts_with("SEG") {
|
||||
let naps = if s.contains("Y") || rest.starts_with("Y") {
|
||||
X
|
||||
} else {
|
||||
N(0)
|
||||
};
|
||||
return Some(DualCore(naps));
|
||||
}
|
||||
if s.starts_with("SIE") {
|
||||
return Some(Siesta);
|
||||
}
|
||||
if s.starts_with("E") {
|
||||
return Some(Everyman(Self::detect_naps(&s_orig).unwrap_or(N(3))));
|
||||
}
|
||||
if s.starts_with("DC") || s.starts_with("DUAL") {
|
||||
return Some(DualCore(Self::detect_naps(&s_orig).unwrap_or(N(0))));
|
||||
}
|
||||
if s.starts_with("TH") || s.starts_with("TP") {
|
||||
return Some(Thinkphasic(Self::detect_naps(&s_orig).unwrap_or(N(1))));
|
||||
}
|
||||
if s.starts_with("TC") || s.starts_with("TRI") {
|
||||
if s.contains("CA") || s.contains("MAY") {
|
||||
return Some(TriCore(AMAYL));
|
||||
}
|
||||
if s.contains("MA") {
|
||||
return Some(Trimaxion);
|
||||
}
|
||||
return Some(TriCore(Self::detect_naps(&s_orig).unwrap_or(N(0))));
|
||||
}
|
||||
if s.starts_with("QC") || s.starts_with("QUAD") {
|
||||
return Some(QuadCore(Self::detect_naps(&s_orig).unwrap_or(N(0))));
|
||||
}
|
||||
if s.starts_with("U") || s.starts_with("TES") {
|
||||
return Some(Uberman(
|
||||
Self::detect_naps(&s_orig).unwrap_or(N(if s.starts_with("TES") { 4 } else { 6 })),
|
||||
));
|
||||
}
|
||||
if s.starts_with("DY") {
|
||||
return Some(Uberman30(
|
||||
Self::detect_naps(&s_orig)
|
||||
.map(|x| match x {
|
||||
X => N(4),
|
||||
x => x,
|
||||
})
|
||||
.unwrap_or(N(4)),
|
||||
));
|
||||
}
|
||||
if s.starts_with("ZO") || s.starts_with("ZB") {
|
||||
return Some(Zoidberg(Self::detect_naps(&s_orig).unwrap_or(N(6))));
|
||||
}
|
||||
Self::find_amayl(s)
|
||||
}
|
||||
#[rustfmt::skip]
|
||||
pub fn short_id(&self) -> String {
|
||||
use NapAmount::*;
|
||||
use ScheduleKind::*;
|
||||
match self {
|
||||
Everyman(N(0)) => format!("Mono"),
|
||||
Siesta => format!("Siesta"),
|
||||
Everyman(X) => format!("BiX"),
|
||||
Everyman(N(n)) => format!("E{n}"),
|
||||
Everyman(AMAYL) => format!("SEVA"),
|
||||
DualCore(X) => format!("SegY"),
|
||||
DualCore(N(n)) => format!("DC{n}"),
|
||||
DualCore(AMAYL) => format!("DUCA"),
|
||||
Thinkphasic(X) => format!("TPX"),
|
||||
Thinkphasic(N(n)) => format!("TP{n}"),
|
||||
Thinkphasic(AMAYL) => format!("THAMAYL"),
|
||||
TriCore(X) => format!("TCX"),
|
||||
TriCore(N(n)) => format!("TC{n}"),
|
||||
TriCore(AMAYL) => format!("TRICA"),
|
||||
QuadCore(X) => format!("QCX"),
|
||||
QuadCore(N(n)) => format!("QC{n}"),
|
||||
QuadCore(AMAYL) => format!("QCA"),
|
||||
CAMAYL => format!("CAMA"),
|
||||
Uberman(X) => format!("UX"),
|
||||
Uberman(N(4)) => format!("Tesla"),
|
||||
Uberman(N(n)) => format!("U{n}"),
|
||||
Uberman(AMAYL) => format!("SPAM"),
|
||||
Uberman30(X) => format!("invalid"),
|
||||
Uberman30(N(4)) => format!("Dymax"),
|
||||
Uberman30(N(n)) => format!("Dymax{n}"),
|
||||
Uberman30(AMAYL) => format!("SDMA"),
|
||||
Bimaxion => format!("Bimax"),
|
||||
Trimaxion => format!("Trimax"),
|
||||
Zoidberg(X) => format!("ZBX"),
|
||||
Zoidberg(N(6)) => format!("ZB"),
|
||||
Zoidberg(N(n)) => format!("ZB{n}"),
|
||||
Zoidberg(AMAYL) => format!("ZOIDA"),
|
||||
}
|
||||
}
|
||||
#[rustfmt::skip]
|
||||
pub fn long_id(&self) -> String {
|
||||
use NapAmount::*;
|
||||
use ScheduleKind::*;
|
||||
match self {
|
||||
Everyman(N(0)) => format!("Monophasic"),
|
||||
Siesta => format!("Siesta"),
|
||||
Everyman(X) => format!("Biphasic-X"),
|
||||
Everyman(N(n)) => format!("Everyman-{n}"),
|
||||
Everyman(AMAYL) => format!("SEVAMAYL"),
|
||||
DualCore(X) => format!("Segmented-Y"),
|
||||
DualCore(N(n)) => format!("DualCore-{n}"),
|
||||
DualCore(AMAYL) => format!("DUCAMAYL"),
|
||||
Thinkphasic(X) => format!("Thinkphasic-X"),
|
||||
Thinkphasic(N(n)) => format!("Thinkphasic-{n}"),
|
||||
Thinkphasic(AMAYL) => format!("THINKAMAYL"),
|
||||
TriCore(X) => format!("TriCore-X"),
|
||||
TriCore(N(n)) => format!("TriCore-{n}"),
|
||||
TriCore(AMAYL) => format!("TRICAMAYL"),
|
||||
QuadCore(X) => format!("QuadCore-X"),
|
||||
QuadCore(N(n)) => format!("QuadCore-{n}"),
|
||||
QuadCore(AMAYL) => format!("QCAMAYL"),
|
||||
CAMAYL => format!("CAMAYL"),
|
||||
Uberman(X) => format!("Uberman-X"),
|
||||
Uberman(N(4)) => format!("Tesla"),
|
||||
Uberman(N(n)) => format!("Uberman-{n}"),
|
||||
Uberman(AMAYL) => format!("SPAMAYL"),
|
||||
Uberman30(X) => format!("invalid"),
|
||||
Uberman30(N(4)) => format!("Dymaxion"),
|
||||
Uberman30(N(n)) => format!("Dymaxion-{n}"),
|
||||
Uberman30(AMAYL) => format!("SDYMAMAYL"),
|
||||
Bimaxion => format!("Bimaxion"),
|
||||
Trimaxion => format!("Trimaxion"),
|
||||
Zoidberg(X) => format!("Zoidberg-X"),
|
||||
Zoidberg(N(6)) => format!("Zoidberg"),
|
||||
Zoidberg(N(n)) => format!("Zoidberg-{n}"),
|
||||
Zoidberg(AMAYL) => format!("ZOIDAMAYL"),
|
||||
}
|
||||
}
|
||||
fn find_amayl(mut s: &str) -> Option<ScheduleKind> {
|
||||
use NapAmount::*;
|
||||
use ScheduleKind::*;
|
||||
if s.starts_with("S") {
|
||||
s = &s[1..];
|
||||
}
|
||||
if s.starts_with("EV") {
|
||||
return Some(Everyman(AMAYL));
|
||||
}
|
||||
if s.starts_with("PA") {
|
||||
return Some(Uberman(AMAYL));
|
||||
}
|
||||
if s.starts_with("DMA") || s.starts_with("DYMA") {
|
||||
return Some(Uberman30(AMAYL));
|
||||
}
|
||||
if s.starts_with("DUCA") {
|
||||
return Some(DualCore(AMAYL));
|
||||
}
|
||||
if s.starts_with("CAM") {
|
||||
return Some(CAMAYL);
|
||||
}
|
||||
if s.starts_with("TCA") || s.starts_with("TRICA") {
|
||||
return Some(TriCore(AMAYL));
|
||||
}
|
||||
if s.contains("Q") && s.contains("A") {
|
||||
return Some(QuadCore(AMAYL));
|
||||
}
|
||||
if s.starts_with("ZOIDA") {
|
||||
return Some(Zoidberg(AMAYL));
|
||||
}
|
||||
if s.starts_with("THA") || s.starts_with("TPA") || s.starts_with("THINKA") {
|
||||
return Some(Thinkphasic(AMAYL));
|
||||
}
|
||||
None
|
||||
}
|
||||
fn detect_naps(full_name: &str) -> Option<NapAmount> {
|
||||
full_name
|
||||
.find(|x: char| x.is_numeric() || x == 'X')
|
||||
.map(|begin| {
|
||||
let xcheck = &full_name[begin - 1..=begin];
|
||||
if xcheck == "EX" || xcheck == "LX" {
|
||||
return None;
|
||||
}
|
||||
full_name[begin..]
|
||||
.find(|x: char| !x.is_numeric() && x != 'X')
|
||||
.or(Some(full_name.len() - begin))
|
||||
.map(|end| (begin, end + begin))
|
||||
})
|
||||
.flatten()
|
||||
.map(|(begin, end)| {
|
||||
let s = &full_name[begin..end];
|
||||
if s == "X" {
|
||||
return Some(NapAmount::X);
|
||||
}
|
||||
Some(NapAmount::N(s.parse::<u8>().ok()?))
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Schedule {
|
||||
kind: ScheduleKind,
|
||||
extended: bool,
|
||||
flexible: bool,
|
||||
stiff: bool,
|
||||
modified: bool,
|
||||
shortened: bool,
|
||||
recovery: bool,
|
||||
}
|
||||
|
||||
impl Schedule {
|
||||
pub fn from_ident(s: &str) -> Option<Self> {
|
||||
let s = s.to_uppercase();
|
||||
let kind = ScheduleKind::from_ident(&s)?;
|
||||
let Some(begin) = try_find_with_number(&s)
|
||||
.or(try_find_with_dash(&s))
|
||||
.or(try_find_by_string(&s))
|
||||
else {
|
||||
return Some(Self {
|
||||
kind,
|
||||
extended: false,
|
||||
flexible: false,
|
||||
stiff: false,
|
||||
modified: false,
|
||||
shortened: false,
|
||||
recovery: false,
|
||||
});
|
||||
};
|
||||
let s = &s[begin..];
|
||||
let flexible = s.contains("FLEX") || s.contains("FLX");
|
||||
let s = s.replace("FLEX", "----");
|
||||
let extended = s.contains("EX") || s == "E";
|
||||
let stiff = s.contains("STIFF");
|
||||
let shortened = s.contains("SHO");
|
||||
let modified = s.contains("MOD") || s.contains("MD");
|
||||
let recovery = s.contains("REC");
|
||||
Some(Self {
|
||||
kind,
|
||||
extended,
|
||||
flexible,
|
||||
stiff,
|
||||
modified,
|
||||
shortened,
|
||||
recovery,
|
||||
})
|
||||
}
|
||||
pub fn short_id(&self) -> String {
|
||||
let mut id = self.kind.short_id();
|
||||
if self.shortened {
|
||||
id += "sho";
|
||||
}
|
||||
if self.stiff {
|
||||
id += "stiff"
|
||||
}
|
||||
if self.extended {
|
||||
if !self.flexible && !self.stiff && !self.shortened && !self.modified && !self.recovery
|
||||
{
|
||||
id += "e";
|
||||
} else {
|
||||
id += "ex";
|
||||
}
|
||||
}
|
||||
if self.flexible {
|
||||
id += "flex";
|
||||
}
|
||||
if self.modified {
|
||||
id += "mod";
|
||||
}
|
||||
if self.recovery {
|
||||
id += "rec";
|
||||
}
|
||||
id
|
||||
}
|
||||
pub fn long_id(&self) -> String {
|
||||
let mut id = self.kind.long_id();
|
||||
if self.shortened {
|
||||
id += "-Shortened";
|
||||
}
|
||||
if self.stiff {
|
||||
id += "-Stiff"
|
||||
}
|
||||
if self.extended {
|
||||
id += "-Extended"
|
||||
}
|
||||
if self.flexible {
|
||||
id += "-Flexible";
|
||||
}
|
||||
if self.modified {
|
||||
id += "-Modified";
|
||||
}
|
||||
if self.recovery {
|
||||
id += "-Recovery";
|
||||
}
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
fn try_find_with_number(s: &str) -> Option<usize> {
|
||||
s.rfind(char::is_numeric).map(|x| x + 1)
|
||||
}
|
||||
|
||||
fn try_find_with_dash(s: &str) -> Option<usize> {
|
||||
s.find('-').map(|x| x + 1)
|
||||
}
|
||||
|
||||
fn try_find_by_string(s: &str) -> Option<usize> {
|
||||
s.find("EX")
|
||||
.or(s.find("MOD"))
|
||||
.or(s.find("MD"))
|
||||
.or(s.find("FLEX"))
|
||||
.or(s.find("FLX"))
|
||||
.or(s.find("STIFF"))
|
||||
.or(s.find("SHO"))
|
||||
.or(s.find("REC"))
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue