Skip to content

Commit

Permalink
new commands, remove valid() method
Browse files Browse the repository at this point in the history
  • Loading branch information
geremachek committed Aug 21, 2021
1 parent 2ab50cb commit b5f63c3
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 81 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "merlin"
version = "1.2.1"
version = "1.3.0"
authors = ["geremachek <[email protected]>"]
edition = "2018"

Expand Down
143 changes: 70 additions & 73 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub enum Command {
Burn,
Shave,
Molecule,
Atoms,
Pen,
Orbit,
Decay,
Expand All @@ -40,6 +41,8 @@ pub enum Command {
Scribe,
Adieu,
Nomen,
Disenchant,
Smash,
Merlin,
Summon,
Dub,
Expand All @@ -52,91 +55,85 @@ impl FromStr for Command {

fn from_str(cmd: &str) -> Result<Self, Self::Err> {
match cmd {
"genesis" => Ok(Command::Genesis),
"spine" => Ok(Command::Spine),
"carved" => Ok(Command::Carved),
"incant" => Ok(Command::Incant),
"infuse" => Ok(Command::Infuse),
"shelve" => Ok(Command::Shelve),
"focus" => Ok(Command::Focus),
"volume" => Ok(Command::Volume),
"volumes" => Ok(Command::Volumes),
"spot" => Ok(Command::Spot),
"span" => Ok(Command::Span),
"pin" => Ok(Command::Pin),
"columns" => Ok(Command::Columns),
"traverse" => Ok(Command::Traverse),
"shift" => Ok(Command::Shift),
"appear" => Ok(Command::Appear),
"infix" => Ok(Command::Infix),
"peer" => Ok(Command::Peer),
"inscribe" => Ok(Command::Inscribe),
"trample" => Ok(Command::Trample),
"burn" => Ok(Command::Burn),
"shave" => Ok(Command::Shave),
"molecule" => Ok(Command::Molecule),
"pen" => Ok(Command::Pen),
"orbit" => Ok(Command::Orbit),
"decay" => Ok(Command::Decay),
"destroy" => Ok(Command::Destroy),
"tether" => Ok(Command::Tether),
"fray" => Ok(Command::Fray),
"mirror" => Ok(Command::Mirror),
"atom" => Ok(Command::Atom),
"scribe" => Ok(Command::Scribe),
"adieu" => Ok(Command::Adieu),
"nomen" => Ok(Command::Nomen),
"merlin" => Ok(Command::Merlin),
"summon" => Ok(Command::Summon),
"dub" => Ok(Command::Dub),
"carve" => Ok(Command::Carve),
"spellbook" => Ok(Command::Spellbook),
_ => Err(MerlinError::UnknownCommand),
"genesis" => Ok(Command::Genesis),
"spine" => Ok(Command::Spine),
"carved" => Ok(Command::Carved),
"incant" => Ok(Command::Incant),
"infuse" => Ok(Command::Infuse),
"shelve" => Ok(Command::Shelve),
"focus" => Ok(Command::Focus),
"volume" => Ok(Command::Volume),
"volumes" => Ok(Command::Volumes),
"spot" => Ok(Command::Spot),
"span" => Ok(Command::Span),
"pin" => Ok(Command::Pin),
"columns" => Ok(Command::Columns),
"traverse" => Ok(Command::Traverse),
"shift" => Ok(Command::Shift),
"appear" => Ok(Command::Appear),
"infix" => Ok(Command::Infix),
"peer" => Ok(Command::Peer),
"inscribe" => Ok(Command::Inscribe),
"trample" => Ok(Command::Trample),
"burn" => Ok(Command::Burn),
"shave" => Ok(Command::Shave),
"molecule" => Ok(Command::Molecule),
"atoms" => Ok(Command::Atoms),
"pen" => Ok(Command::Pen),
"orbit" => Ok(Command::Orbit),
"decay" => Ok(Command::Decay),
"destroy" => Ok(Command::Destroy),
"tether" => Ok(Command::Tether),
"fray" => Ok(Command::Fray),
"mirror" => Ok(Command::Mirror),
"atom" => Ok(Command::Atom),
"scribe" => Ok(Command::Scribe),
"adieu" => Ok(Command::Adieu),
"nomen" => Ok(Command::Nomen),
"disenchant" => Ok(Command::Disenchant),
"smash" => Ok(Command::Smash),
"merlin" => Ok(Command::Merlin),
"summon" => Ok(Command::Summon),
"dub" => Ok(Command::Dub),
"carve" => Ok(Command::Carve),
"spellbook" => Ok(Command::Spellbook),
_ => Err(MerlinError::UnknownCommand),
}
}
}

impl Command {
// check if the right amount of arguments have been supplied

fn valid(&self, args: usize) -> bool {
match self {
Command::Genesis | Command::Spot | Command::Span | Command::Pin | Command::Columns | Command::Molecule | Command::Pen | Command::Orbit |
Command::Decay | Command::Destroy | Command::Mirror | Command::Atom | Command::Scribe | Command::Adieu | Command::Carve | Command::Burn | Command::Volume |
Command::Volumes | Command::Carved => true,
Command::Focus | Command::Traverse | Command::Appear | Command::Shave | Command::Shelve | Command::Incant | Command::Inscribe | Command::Trample | Command::Summon |
Command::Dub | Command::Spellbook | Command::Shift | Command::Infix | Command::Spine | Command::Nomen | Command::Merlin => args >= 1,
Command::Infuse | Command::Tether | Command::Fray | Command::Peer => args >= 2,
}
}

// check if the number of arguments are valid, and if so return the needed amount of arguments

pub fn get_needed(&self, args: usize) -> Result<usize, MerlinError> {
if self.valid(args) {
// choose the number of atoms we need, based on those available
// choose the number of atoms we need, based on those available

let choose_mm = |max, min| {
if args >= max {
return max;
}
let choose_mm = |max, min| {
if args >= max {
max
} else {
min
}
};

return min;
};
let needed = match self {
Command::Tether => choose_mm(3, args+1), // we need a minimum of 3
Command::Nomen => choose_mm(2, args+1), // min of 1
Command::Spot | Command::Span | Command::Molecule | Command::Pen | Command::Orbit | Command::Decay | Command::Destroy | Command::Mirror |
Command::Atom | Command::Scribe | Command::Adieu | Command::Carve | Command::Pin | Command::Columns | Command::Burn | Command::Volume |
Command::Volumes | Command::Carved | Command::Atoms => 0,
Command::Focus | Command::Traverse | Command::Appear | Command::Shave | Command::Shelve | Command::Inscribe | Command::Trample | Command::Incant |
Command::Summon | Command::Dub | Command::Spellbook | Command::Shift | Command::Infix | Command::Spine | Command::Merlin | Command::Disenchant |
Command::Smash => 1,
Command::Infuse | Command::Peer | Command::Fray => 2,
Command::Genesis => choose_mm(1, 0),
};

match self {
Command::Tether | Command::Nomen => return Ok(args),
Command::Spot | Command::Span | Command::Molecule | Command::Pen | Command::Orbit | Command::Decay | Command::Destroy | Command::Mirror |
Command::Atom | Command::Scribe | Command::Adieu | Command::Carve | Command::Pin | Command::Columns | Command::Burn | Command::Volume |
Command::Volumes | Command::Carved => return Ok(0),
Command::Focus | Command::Traverse | Command::Appear | Command::Shave | Command::Shelve | Command::Inscribe | Command::Trample | Command::Incant |
Command::Summon | Command::Dub | Command::Spellbook | Command::Shift | Command::Infix | Command::Spine | Command::Merlin => return Ok(1),
Command::Infuse | Command::Peer | Command::Fray => return Ok(2),
Command::Genesis => return Ok(choose_mm(1, 0))
}
if needed <= args {
Ok(needed)
} else {
Err(MerlinError::InvalidOrNoArguments)
}

return Err(MerlinError::InvalidOrNoArguments);
}

}
4 changes: 3 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub enum MerlinError {
ReadFailed,
FileAlreadyExists,
BufferNotNamed,
UnknownNomen,
}

impl fmt::Display for MerlinError {
Expand All @@ -28,7 +29,8 @@ impl fmt::Display for MerlinError {
MerlinError::CreationOrWriteFailed => "failed to create / write a file",
MerlinError::ReadFailed => "failed to read a file",
MerlinError::FileAlreadyExists => "file already exists",
MerlinError::BufferNotNamed => "buffer is not named"
MerlinError::BufferNotNamed => "buffer is not named",
MerlinError::UnknownNomen => "unknown nomen",
};

write!(f, "merlin: {}", msg)
Expand Down
8 changes: 7 additions & 1 deletion src/plane/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{volume::Volume};
use crate::{volume::Volume, error::MerlinError};
use stack::Stack;
use nomen::Nomen;

Expand Down Expand Up @@ -75,6 +75,12 @@ impl Plane {
self.nomens.iter().position(|n| n == name)
}

// get_nomen but it returns an error if it can't find what it's looking for

fn get_nomen_err(&self, name: &str) -> Result<usize, MerlinError> {
self.get_nomen(name).ok_or(MerlinError::UnknownNomen)
}

// add a new volume

fn push_volume(&mut self, v: Volume) {
Expand Down
3 changes: 3 additions & 0 deletions src/plane/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ impl Plane {
let n = data.pop().unwrap();
self.nomen(data, n);
}
Command::Disenchant => self.disenchant(&data[0])?,
Command::Smash => self.smash(&data[0])?,
Command::Merlin => {
// make sure we are always *starting* in atom mode, but preserving the original mode
// for when we finish parsing
Expand All @@ -159,6 +161,7 @@ impl Plane {
Command::Spellbook => self.spellbook(&data[0])?,
Command::Volume => return oksome(self.volume().to_string()),
Command::Volumes => return oksome(self.volumes.len().to_string()),
Command::Atoms => return oksome(self.stack.len().to_string()),
_ => { // the following commands require buffers to be open
if self.volumes.len() > 0 { // buffers / files are open
let cvol = &mut self.volumes[self.current_volume]; // current volume
Expand Down
25 changes: 21 additions & 4 deletions src/plane/plane_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,30 @@ impl Plane {
Ok(())
}

// "clear" a nomen

pub fn disenchant(&mut self, name: &str) -> Result<(), MerlinError> {
// empty the vector of atoms for a certain nomen, reutrn an error if we can't find it

let nomen_index = self.get_nomen_err(name)?;
Ok(self.nomens[nomen_index]
.atoms
.clear())
}

// remove a nomen

pub fn smash(&mut self, name: &str) -> Result<(), MerlinError> {
// remove the nomen from the list if it exists, otherwise return an error

let _ = self.nomens.remove(self.get_nomen_err(name)?);
Ok(())
}

// create a new nomen

pub fn nomen(&mut self, atoms: Vec<String>, name: String) {
if let Some(i) = self.get_nomen(&name) {
self.nomens.remove(i);
}

let _ = self.smash(&name); // remove the nomen if it exists
self.nomens.push(Nomen::new(name, atoms))
}

Expand Down

0 comments on commit b5f63c3

Please sign in to comment.