Commit 41ff9ecb authored by Michael Aaron Murphy's avatar Michael Aaron Murphy
Browse files

Public items now have crate-level visibility

This is the next step towards using Ion as a library for an upcoming project.
parent a61f0ec9
...@@ -5,11 +5,11 @@ use std::ops::DerefMut; ...@@ -5,11 +5,11 @@ use std::ops::DerefMut;
// TODO: These could be generalised to work on non-ASCII characters (and even // TODO: These could be generalised to work on non-ASCII characters (and even
// strings!) as long as the byte size of the needle and haystack match. // strings!) as long as the byte size of the needle and haystack match.
pub trait AsciiReplaceInPlace { pub(crate) trait AsciiReplaceInPlace {
fn ascii_replace_in_place(&mut self, needle: char, haystack: char); fn ascii_replace_in_place(&mut self, needle: char, haystack: char);
} }
pub trait AsciiReplace: Sized { pub(crate) trait AsciiReplace: Sized {
fn ascii_replace(self, needle: char, haystack: char) -> Self; fn ascii_replace(self, needle: char, haystack: char) -> Self;
} }
......
...@@ -8,7 +8,7 @@ fn calc_or_polish_calc(args: String) -> Result<Value, CalcError> { ...@@ -8,7 +8,7 @@ fn calc_or_polish_calc(args: String) -> Result<Value, CalcError> {
} }
} }
pub fn calc(args: &[&str]) -> Result<(), String> { pub(crate) fn calc(args: &[&str]) -> Result<(), String> {
let stdout = io::stdout(); let stdout = io::stdout();
let mut stdout = stdout.lock(); let mut stdout = stdout.lock();
if !args.is_empty() { if !args.is_empty() {
......
...@@ -3,7 +3,7 @@ use shell::status::*; ...@@ -3,7 +3,7 @@ use shell::status::*;
macro_rules! string_function { macro_rules! string_function {
($method:tt) => ( ($method:tt) => (
pub fn $method(args: &[&str], _: &mut Shell) -> i32 { pub(crate) fn $method(args: &[&str], _: &mut Shell) -> i32 {
match args.len() { match args.len() {
0...2 => { 0...2 => {
eprintln!("ion: {}: two arguments must be supplied", args[0]); eprintln!("ion: {}: two arguments must be supplied", args[0]);
......
...@@ -41,7 +41,7 @@ OPTIONS ...@@ -41,7 +41,7 @@ OPTIONS
\v vertical tab (VT) \v vertical tab (VT)
"#; // @MANEND "#; // @MANEND
pub fn echo(args: &[&str]) -> Result<(), io::Error> { pub(crate) fn echo(args: &[&str]) -> Result<(), io::Error> {
let mut flags = Flags::empty(); let mut flags = Flags::empty();
let mut data: Vec<&str> = vec![]; let mut data: Vec<&str> = vec![];
......
...@@ -70,7 +70,7 @@ AUTHOR ...@@ -70,7 +70,7 @@ AUTHOR
Heavily based on implementation of the test builtin, which was written by Michael Murph. Heavily based on implementation of the test builtin, which was written by Michael Murph.
"#; // @MANEND "#; // @MANEND
pub fn exists(args: &[&str], shell: &Shell) -> Result<bool, String> { pub(crate) fn exists(args: &[&str], shell: &Shell) -> Result<bool, String> {
let stdout = io::stdout(); let stdout = io::stdout();
let mut buffer = BufWriter::new(stdout.lock()); let mut buffer = BufWriter::new(stdout.lock());
......
...@@ -18,7 +18,7 @@ fn print_functions(functions: &FnvHashMap<Identifier, Function>) { ...@@ -18,7 +18,7 @@ fn print_functions(functions: &FnvHashMap<Identifier, Function>) {
} }
} }
pub fn fn_(functions: &mut FnvHashMap<Identifier, Function>) -> i32 { pub(crate) fn fn_(functions: &mut FnvHashMap<Identifier, Function>) -> i32 {
print_functions(functions); print_functions(functions);
SUCCESS SUCCESS
} }
...@@ -6,7 +6,7 @@ use std::process::Command; ...@@ -6,7 +6,7 @@ use std::process::Command;
const DOCPATH: &str = "/usr/share/ion/docs/index.html"; const DOCPATH: &str = "/usr/share/ion/docs/index.html";
pub fn ion_docs(_: &[&str], shell: &mut Shell) -> i32 { pub(crate) fn ion_docs(_: &[&str], shell: &mut Shell) -> i32 {
if !Path::new(DOCPATH).exists() { if !Path::new(DOCPATH).exists() {
eprintln!("ion: ion shell documentation is not installed"); eprintln!("ion: ion shell documentation is not installed");
return FAILURE; return FAILURE;
......
...@@ -9,7 +9,7 @@ use std::io::{stderr, Write}; ...@@ -9,7 +9,7 @@ use std::io::{stderr, Write};
/// Disowns given process job IDs, and optionally marks jobs to not receive SIGHUP signals. /// Disowns given process job IDs, and optionally marks jobs to not receive SIGHUP signals.
/// The `-a` flag selects all jobs, `-r` selects all running jobs, and `-h` specifies to mark /// The `-a` flag selects all jobs, `-r` selects all running jobs, and `-h` specifies to mark
/// SIGHUP ignoral. /// SIGHUP ignoral.
pub fn disown(shell: &mut Shell, args: &[&str]) -> i32 { pub(crate) fn disown(shell: &mut Shell, args: &[&str]) -> i32 {
let stderr = stderr(); let stderr = stderr();
let mut stderr = stderr.lock(); let mut stderr = stderr.lock();
const NO_SIGHUP: u8 = 1; const NO_SIGHUP: u8 = 1;
...@@ -75,7 +75,7 @@ pub fn disown(shell: &mut Shell, args: &[&str]) -> i32 { ...@@ -75,7 +75,7 @@ pub fn disown(shell: &mut Shell, args: &[&str]) -> i32 {
} }
/// Display a list of all jobs running in the background. /// Display a list of all jobs running in the background.
pub fn jobs(shell: &mut Shell) { pub(crate) fn jobs(shell: &mut Shell) {
let stderr = stderr(); let stderr = stderr();
let mut stderr = stderr.lock(); let mut stderr = stderr.lock();
for (id, process) in shell.background.lock().unwrap().iter().enumerate() { for (id, process) in shell.background.lock().unwrap().iter().enumerate() {
...@@ -89,7 +89,7 @@ pub fn jobs(shell: &mut Shell) { ...@@ -89,7 +89,7 @@ pub fn jobs(shell: &mut Shell) {
/// Hands control of the foreground process to the specified jobs, recording their exit status. /// Hands control of the foreground process to the specified jobs, recording their exit status.
/// If the job is stopped, the job will be resumed. /// If the job is stopped, the job will be resumed.
/// If multiple jobs are given, then only the last job's exit status will be returned. /// If multiple jobs are given, then only the last job's exit status will be returned.
pub fn fg(shell: &mut Shell, args: &[&str]) -> i32 { pub(crate) fn fg(shell: &mut Shell, args: &[&str]) -> i32 {
fn fg_job(shell: &mut Shell, njob: u32) -> i32 { fn fg_job(shell: &mut Shell, njob: u32) -> i32 {
let job; let job;
if let Some(borrowed_job) = shell.background.lock().unwrap().iter().nth(njob as usize) { if let Some(borrowed_job) = shell.background.lock().unwrap().iter().nth(njob as usize) {
...@@ -140,7 +140,7 @@ pub fn fg(shell: &mut Shell, args: &[&str]) -> i32 { ...@@ -140,7 +140,7 @@ pub fn fg(shell: &mut Shell, args: &[&str]) -> i32 {
} }
/// Resumes a stopped background process, if it was stopped. /// Resumes a stopped background process, if it was stopped.
pub fn bg(shell: &mut Shell, args: &[&str]) -> i32 { pub(crate) fn bg(shell: &mut Shell, args: &[&str]) -> i32 {
fn bg_job(shell: &mut Shell, njob: u32) -> bool { fn bg_job(shell: &mut Shell, njob: u32) -> bool {
if let Some(job) = shell.background.lock().unwrap().iter_mut().nth(njob as usize) { if let Some(job) = shell.background.lock().unwrap().iter_mut().nth(njob as usize) {
match job.state { match job.state {
......
...@@ -33,7 +33,7 @@ use sys; ...@@ -33,7 +33,7 @@ use sys;
/// Structure which represents a Terminal's command. /// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the /// This command structure contains a name, and the code which run the
/// functionnality associated to this one, with zero, one or several argument(s). /// functionnality associated to this one, with zero, one or several argument(s).
pub struct Builtin { pub(crate) struct Builtin {
pub name: &'static str, pub name: &'static str,
pub help: &'static str, pub help: &'static str,
pub main: fn(&[&str], &mut Shell) -> i32, pub main: fn(&[&str], &mut Shell) -> i32,
...@@ -41,7 +41,7 @@ pub struct Builtin { ...@@ -41,7 +41,7 @@ pub struct Builtin {
impl Builtin { impl Builtin {
/// Return the map from command names to commands /// Return the map from command names to commands
pub fn map() -> FnvHashMap<&'static str, Self> { pub(crate) fn map() -> FnvHashMap<&'static str, Self> {
let mut commands: FnvHashMap<&str, Self> = let mut commands: FnvHashMap<&str, Self> =
FnvHashMap::with_capacity_and_hasher(32, Default::default()); FnvHashMap::with_capacity_and_hasher(32, Default::default());
......
...@@ -35,7 +35,7 @@ enum PositionalArgs { ...@@ -35,7 +35,7 @@ enum PositionalArgs {
use self::PositionalArgs::*; use self::PositionalArgs::*;
pub fn set(args: &[&str], shell: &mut Shell) -> i32 { pub(crate) fn set(args: &[&str], shell: &mut Shell) -> i32 {
let stdout = io::stdout(); let stdout = io::stdout();
let stderr = io::stderr(); let stderr = io::stderr();
let mut args_iter = args.iter(); let mut args_iter = args.iter();
......
...@@ -3,7 +3,7 @@ use std::fs::File; ...@@ -3,7 +3,7 @@ use std::fs::File;
use std::io::Read; use std::io::Read;
/// Evaluates the given file and returns 'SUCCESS' if it succeeds. /// Evaluates the given file and returns 'SUCCESS' if it succeeds.
pub fn source(shell: &mut Shell, arguments: &[&str]) -> Result<(), String> { pub(crate) fn source(shell: &mut Shell, arguments: &[&str]) -> Result<(), String> {
match arguments.get(1) { match arguments.get(1) {
Some(argument) => if let Ok(mut file) = File::open(&argument) { Some(argument) => if let Ok(mut file) = File::open(&argument) {
let capacity = file.metadata().map(|x| x.len()).unwrap_or(0) as usize; let capacity = file.metadata().map(|x| x.len()).unwrap_or(0) as usize;
......
...@@ -111,7 +111,7 @@ AUTHOR ...@@ -111,7 +111,7 @@ AUTHOR
Written by Michael Murphy. Written by Michael Murphy.
"#; // @MANEND "#; // @MANEND
pub fn test(args: &[&str]) -> Result<bool, String> { pub(crate) fn test(args: &[&str]) -> Result<bool, String> {
let stdout = io::stdout(); let stdout = io::stdout();
let mut buffer = BufWriter::new(stdout.lock()); let mut buffer = BufWriter::new(stdout.lock());
......
...@@ -18,7 +18,7 @@ OPTIONS ...@@ -18,7 +18,7 @@ OPTIONS
display this help and exit display this help and exit
"#; "#;
pub fn time(args: &[&str]) -> Result<(), String> { pub(crate) fn time(args: &[&str]) -> Result<(), String> {
let stdout = stdout(); let stdout = stdout();
let mut stdout = stdout.lock(); let mut stdout = stdout.lock();
......
...@@ -112,7 +112,7 @@ fn parse_alias(args: &str) -> Binding { ...@@ -112,7 +112,7 @@ fn parse_alias(args: &str) -> Binding {
/// The `alias` command will define an alias for another command, and thus may be used as a /// The `alias` command will define an alias for another command, and thus may be used as a
/// command itself. /// command itself.
pub fn alias(vars: &mut Variables, args: &str) -> i32 { pub(crate) fn alias(vars: &mut Variables, args: &str) -> i32 {
match parse_alias(args) { match parse_alias(args) {
Binding::InvalidKey(key) => { Binding::InvalidKey(key) => {
let stderr = io::stderr(); let stderr = io::stderr();
...@@ -139,7 +139,7 @@ pub fn alias(vars: &mut Variables, args: &str) -> i32 { ...@@ -139,7 +139,7 @@ pub fn alias(vars: &mut Variables, args: &str) -> i32 {
/// Dropping an alias will erase it from the shell. /// Dropping an alias will erase it from the shell.
pub fn drop_alias<I: IntoIterator>(vars: &mut Variables, args: I) -> i32 pub(crate) fn drop_alias<I: IntoIterator>(vars: &mut Variables, args: I) -> i32
where I::Item: AsRef<str> where I::Item: AsRef<str>
{ {
let args = args.into_iter().collect::<Vec<I::Item>>(); let args = args.into_iter().collect::<Vec<I::Item>>();
...@@ -159,7 +159,7 @@ pub fn drop_alias<I: IntoIterator>(vars: &mut Variables, args: I) -> i32 ...@@ -159,7 +159,7 @@ pub fn drop_alias<I: IntoIterator>(vars: &mut Variables, args: I) -> i32
} }
/// Dropping an array will erase it from the shell. /// Dropping an array will erase it from the shell.
pub fn drop_array<I: IntoIterator>(vars: &mut Variables, args: I) -> i32 pub(crate) fn drop_array<I: IntoIterator>(vars: &mut Variables, args: I) -> i32
where I::Item: AsRef<str> where I::Item: AsRef<str>
{ {
let args = args.into_iter().collect::<Vec<I::Item>>(); let args = args.into_iter().collect::<Vec<I::Item>>();
...@@ -186,7 +186,7 @@ pub fn drop_array<I: IntoIterator>(vars: &mut Variables, args: I) -> i32 ...@@ -186,7 +186,7 @@ pub fn drop_array<I: IntoIterator>(vars: &mut Variables, args: I) -> i32
} }
/// Dropping a variable will erase it from the shell. /// Dropping a variable will erase it from the shell.
pub fn drop_variable<I: IntoIterator>(vars: &mut Variables, args: I) -> i32 pub(crate) fn drop_variable<I: IntoIterator>(vars: &mut Variables, args: I) -> i32
where I::Item: AsRef<str> where I::Item: AsRef<str>
{ {
let args = args.into_iter().collect::<Vec<I::Item>>(); let args = args.into_iter().collect::<Vec<I::Item>>();
......
...@@ -8,14 +8,14 @@ const ARRAY: u8 = 64; ...@@ -8,14 +8,14 @@ const ARRAY: u8 = 64;
const METHOD: u8 = 128; const METHOD: u8 = 128;
/// An efficient `Iterator` structure for splitting arguments /// An efficient `Iterator` structure for splitting arguments
pub struct ArgumentSplitter<'a> { pub(crate) struct ArgumentSplitter<'a> {
data: &'a str, data: &'a str,
read: usize, read: usize,
flags: u8, flags: u8,
} }
impl<'a> ArgumentSplitter<'a> { impl<'a> ArgumentSplitter<'a> {
pub fn new(data: &'a str) -> ArgumentSplitter<'a> { pub(crate) fn new(data: &'a str) -> ArgumentSplitter<'a> {
ArgumentSplitter { ArgumentSplitter {
data: data, data: data,
read: 0, read: 0,
......
...@@ -4,7 +4,7 @@ use super::super::ArgumentSplitter; ...@@ -4,7 +4,7 @@ use super::super::ArgumentSplitter;
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum AssignmentError<'a> { pub(crate) enum AssignmentError<'a> {
NoKeys, NoKeys,
NoOperator, NoOperator,
NoValues, NoValues,
...@@ -33,7 +33,7 @@ impl<'a> Display for AssignmentError<'a> { ...@@ -33,7 +33,7 @@ impl<'a> Display for AssignmentError<'a> {
/// ///
/// Each request will tell the shell whether the assignment is asking to update an array or a /// Each request will tell the shell whether the assignment is asking to update an array or a
/// string, and will contain the key/value pair to assign. /// string, and will contain the key/value pair to assign.
pub struct AssignmentActions<'a> { pub(crate) struct AssignmentActions<'a> {
keys: KeyIterator<'a>, keys: KeyIterator<'a>,
operator: Operator, operator: Operator,
values: ArgumentSplitter<'a>, values: ArgumentSplitter<'a>,
...@@ -42,7 +42,7 @@ pub struct AssignmentActions<'a> { ...@@ -42,7 +42,7 @@ pub struct AssignmentActions<'a> {
} }
impl<'a> AssignmentActions<'a> { impl<'a> AssignmentActions<'a> {
pub fn new(data: &'a str) -> Result<AssignmentActions<'a>, AssignmentError<'a>> { pub(crate) fn new(data: &'a str) -> Result<AssignmentActions<'a>, AssignmentError<'a>> {
let (keys, op, vals) = split_assignment(data); let (keys, op, vals) = split_assignment(data);
Ok(AssignmentActions { Ok(AssignmentActions {
keys: keys.map(KeyIterator::new).ok_or(AssignmentError::NoKeys)?, keys: keys.map(KeyIterator::new).ok_or(AssignmentError::NoKeys)?,
...@@ -88,7 +88,7 @@ impl<'a> Iterator for AssignmentActions<'a> { ...@@ -88,7 +88,7 @@ impl<'a> Iterator for AssignmentActions<'a> {
/// Providing the key/value pair and operator to use during assignment, this variant defines /// Providing the key/value pair and operator to use during assignment, this variant defines
/// whether the assignment should set a string or array. /// whether the assignment should set a string or array.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Action<'a> { pub(crate) enum Action<'a> {
UpdateString(Key<'a>, Operator, &'a str), UpdateString(Key<'a>, Operator, &'a str),
UpdateArray(Key<'a>, Operator, &'a str), UpdateArray(Key<'a>, Operator, &'a str),
} }
......
...@@ -7,9 +7,9 @@ use super::super::expand_string; ...@@ -7,9 +7,9 @@ use super::super::expand_string;
/// - `[ 1 2 3 ]` = Array /// - `[ 1 2 3 ]` = Array
/// - `[ 1 2 3 ][1]` = String /// - `[ 1 2 3 ][1]` = String
/// - `string` = String /// - `string` = String
pub fn is_array(value: &str) -> bool { value.starts_with('[') && value.ends_with(']') } pub(crate) fn is_array(value: &str) -> bool { value.starts_with('[') && value.ends_with(']') }
pub fn is_boolean(value: &str) -> Result<&str, ()> { pub(crate) fn is_boolean(value: &str) -> Result<&str, ()> {
if ["true", "1", "y"].contains(&value) { if ["true", "1", "y"].contains(&value) {
Ok("true") Ok("true")
} else if ["false", "0", "n"].contains(&value) { } else if ["false", "0", "n"].contains(&value) {
...@@ -108,7 +108,7 @@ fn get_array<E: Expander>(shell: &E, value: &str) -> ReturnValue { ...@@ -108,7 +108,7 @@ fn get_array<E: Expander>(shell: &E, value: &str) -> ReturnValue {
ReturnValue::Vector(expand_string(value, shell, false)) ReturnValue::Vector(expand_string(value, shell, false))
} }
pub fn value_check<'a, E: Expander>( pub(crate) fn value_check<'a, E: Expander>(
shell: &E, shell: &E,
value: &'a str, value: &'a str,
expected: Primitive, expected: Primitive,
......
...@@ -3,7 +3,7 @@ use std::fmt::{self, Display, Formatter}; ...@@ -3,7 +3,7 @@ use std::fmt::{self, Display, Formatter};
/// Keys are used in assignments to define which variable will be set, and whether the correct /// Keys are used in assignments to define which variable will be set, and whether the correct
/// types are being assigned. /// types are being assigned.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Key<'a> { pub(crate) struct Key<'a> {
pub kind: Primitive, pub kind: Primitive,
pub name: &'a str, pub name: &'a str,
} }
...@@ -11,14 +11,14 @@ pub struct Key<'a> { ...@@ -11,14 +11,14 @@ pub struct Key<'a> {
/// Functions require that their keys to have a longer lifetime, and that is made possible /// Functions require that their keys to have a longer lifetime, and that is made possible
/// by eliminating the lifetime requirements via allocating a `String`. /// by eliminating the lifetime requirements via allocating a `String`.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct KeyBuf { pub(crate) struct KeyBuf {
pub kind: Primitive, pub kind: Primitive,
pub name: String, pub name: String,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum TypeError<'a> { pub(crate) enum TypeError<'a> {
Invalid(&'a str), Invalid(&'a str),
BadValue(Primitive), BadValue(Primitive),
} }
...@@ -52,7 +52,7 @@ impl<'a> From<Key<'a>> for KeyBuf { ...@@ -52,7 +52,7 @@ impl<'a> From<Key<'a>> for KeyBuf {
/// A primitive defines the type that a requested value should satisfy. /// A primitive defines the type that a requested value should satisfy.
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
pub enum Primitive { pub(crate) enum Primitive {
Any, Any,
AnyArray, AnyArray,
Str, Str,
...@@ -101,13 +101,13 @@ impl Display for Primitive { ...@@ -101,13 +101,13 @@ impl Display for Primitive {
/// Quite simply, an iterator that returns keys. /// Quite simply, an iterator that returns keys.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct KeyIterator<'a> { pub(crate) struct KeyIterator<'a> {
data: &'a str, data: &'a str,
read: usize, read: usize,
} }
impl<'a> KeyIterator<'a> { impl<'a> KeyIterator<'a> {
pub fn new(data: &'a str) -> KeyIterator<'a> { KeyIterator { data, read: 0 } } pub(crate) fn new(data: &'a str) -> KeyIterator<'a> { KeyIterator { data, read: 0 } }
// Parameters are values that follow the semicolon (':'). // Parameters are values that follow the semicolon (':').
fn parse_parameter(&mut self, name: &'a str) -> Result<Key<'a>, TypeError<'a>> { fn parse_parameter(&mut self, name: &'a str) -> Result<Key<'a>, TypeError<'a>> {
......
...@@ -4,16 +4,16 @@ mod splitter; ...@@ -4,16 +4,16 @@ mod splitter;
mod keys; mod keys;
mod operator; mod operator;
pub use self::actions::{Action, AssignmentActions, AssignmentError}; pub(crate) use self::actions::{Action, AssignmentActions, AssignmentError};
pub use self::checker::{is_array, is_boolean, value_check}; pub(crate) use self::checker::{is_array, value_check};
pub use self::keys::{Key, KeyBuf, KeyIterator, Primitive, TypeError}; pub(crate) use self::keys::{Key, KeyBuf, KeyIterator, Primitive, TypeError};
pub use self::operator::Operator; pub(crate) use self::operator::Operator;
pub use self::splitter::split_assignment; pub(crate) use self::splitter::split_assignment;
use types::{Array, Value}; use types::{Array, Value};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum ReturnValue { pub(crate) enum ReturnValue {
Str(Value), Str(Value),
Vector(Array), Vector(Array),
} }
...@@ -2,7 +2,7 @@ use super::AssignmentError; ...@@ -2,7 +2,7 @@ use super::AssignmentError;
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Clone, Copy)]
pub enum Operator { pub(crate) enum Operator {
Add, Add,
Subtract, Subtract,
Divide, Divide,
...@@ -13,7 +13,7 @@ pub enum Operator { ...@@ -13,7 +13,7 @@ pub enum Operator {
} }
impl Operator { impl Operator {
pub fn parse<'a>(data: &'a str) -> Result<Operator, AssignmentError<'a>> { pub(crate) fn parse<'a>(data: &'a str) -> Result<Operator, AssignmentError<'a>> {
match data { match data {
"=" => Ok(Operator::Equal), "=" => Ok(Operator::Equal),
"+=" => Ok(Operator::Add), "+=" => Ok(Operator::Add),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment