Browse Source

Structure CLI into multiple modules

David Peter 2 years ago
parent
commit
072812ebea
3 changed files with 118 additions and 113 deletions
  1. 24 0
      numbat-cli/src/ansi_formatter.rs
  2. 82 0
      numbat-cli/src/completion.rs
  3. 12 113
      numbat-cli/src/main.rs

+ 24 - 0
numbat-cli/src/ansi_formatter.rs

@@ -0,0 +1,24 @@
+use numbat::markup::{FormatType, FormattedString, Formatter};
+
+use colored::Colorize;
+
+pub struct ANSIFormatter;
+
+impl Formatter for ANSIFormatter {
+    fn format_part(
+        &self,
+        FormattedString(_output_type, format_type, text): &FormattedString,
+    ) -> String {
+        (match format_type {
+            FormatType::Text => text.normal(),
+            FormatType::Keyword => text.magenta(),
+            FormatType::Value => text.yellow(),
+            FormatType::Unit => text.cyan(),
+            FormatType::Identifier => text.red(),
+            FormatType::TypeIdentifier => text.bright_yellow(),
+            FormatType::Operator => text.bold(),
+            FormatType::Decorator => text.yellow(),
+        })
+        .to_string()
+    }
+}

+ 82 - 0
numbat-cli/src/completion.rs

@@ -0,0 +1,82 @@
+use rustyline::{
+    self,
+    completion::{extract_word, Completer, Pair},
+};
+
+pub struct NumbatCompleter;
+
+impl Completer for NumbatCompleter {
+    type Candidate = Pair;
+
+    fn complete(
+        &self,
+        line: &str,
+        pos: usize,
+        _: &rustyline::Context<'_>,
+    ) -> rustyline::Result<(usize, Vec<Self::Candidate>)> {
+        let (pos_word, word_part) = extract_word(line, pos, None, |c| {
+            // TODO: we could use is_identifier_char here potentially
+            match c {
+                c if c.is_alphanumeric() => false,
+                '_' => false,
+                _ => true,
+            }
+        });
+
+        // TODO, obviously
+        let words = vec![
+            "let ",
+            "fn ",
+            "dimension ",
+            "unit ",
+            //
+            "sqrt(",
+            "sqr(",
+            "exp(",
+            "abs(",
+            "round(",
+            "sin(",
+            "atan2(",
+            "toCelsius(",
+            "toKelvin(",
+            "print(",
+            "assert_eq(",
+            //
+            "metric_prefixes",
+            "binary_prefixes",
+            "aliases",
+            "aliases_short",
+            //
+            "gravity",
+            "speed_of_light",
+            //
+            "Scalar",
+            "Length",
+            "Time",
+            "Mass",
+            //
+            "meter",
+            "second",
+            "gram",
+            //
+            "micro",
+            "milli",
+            "centi",
+            "deci",
+            "kilo",
+            "mega",
+        ];
+
+        let candidates = words.iter().filter(|w| w.starts_with(word_part));
+
+        Ok((
+            pos_word,
+            candidates
+                .map(|w| Pair {
+                    display: w.to_string(),
+                    replacement: w.to_string(),
+                })
+                .collect(),
+        ))
+    }
+}

+ 12 - 113
numbat-cli/src/main.rs

@@ -1,27 +1,25 @@
-use std::fs;
-use std::path::PathBuf;
+mod ansi_formatter;
+mod completion;
 
-use numbat::markup::{self, FormatType};
+use ansi_formatter::ANSIFormatter;
+use completion::NumbatCompleter;
+
+use numbat::markup;
 use numbat::pretty_print::PrettyPrint;
-use numbat::{
-    markup::FormattedString, markup::Formatter, Context, ExitStatus, InterpreterResult,
-    NumbatError, ParseError,
-};
+use numbat::{markup::Formatter, Context, ExitStatus, InterpreterResult, NumbatError, ParseError};
 
 use anyhow::{bail, Context as AnyhowContext, Result};
 use clap::Parser;
-use colored::Colorize;
-use rustyline::completion::extract_word;
 use rustyline::config::Configurer;
 use rustyline::{
-    self,
-    completion::{Completer, Pair},
-    error::ReadlineError,
-    history::DefaultHistory,
-    Completer, Editor, Helper, Hinter, Validator,
+    self, error::ReadlineError, history::DefaultHistory, Completer, Editor, Helper, Hinter,
+    Validator,
 };
 use rustyline::{EventHandler, Highlighter, KeyCode, KeyEvent, Modifiers};
 
+use std::fs;
+use std::path::PathBuf;
+
 type ControlFlow = std::ops::ControlFlow<numbat::ExitStatus>;
 
 const PROMPT: &str = ">>> ";
@@ -65,105 +63,6 @@ impl ExecutionMode {
     }
 }
 
-struct ANSIFormatter;
-
-impl Formatter for ANSIFormatter {
-    fn format_part(
-        &self,
-        FormattedString(_output_type, format_type, text): &FormattedString,
-    ) -> String {
-        (match format_type {
-            FormatType::Text => text.normal(),
-            FormatType::Keyword => text.magenta(),
-            FormatType::Value => text.yellow(),
-            FormatType::Unit => text.cyan(),
-            FormatType::Identifier => text.red(),
-            FormatType::TypeIdentifier => text.bright_yellow(),
-            FormatType::Operator => text.bold(),
-            FormatType::Decorator => text.yellow(),
-        })
-        .to_string()
-    }
-}
-
-struct NumbatCompleter;
-
-impl Completer for NumbatCompleter {
-    type Candidate = Pair;
-
-    fn complete(
-        &self,
-        line: &str,
-        pos: usize,
-        _: &rustyline::Context<'_>,
-    ) -> rustyline::Result<(usize, Vec<Self::Candidate>)> {
-        let (pos_word, word_part) = extract_word(line, pos, None, |c| {
-            // TODO: we could use is_identifier_char here potentially
-            match c {
-                c if c.is_alphanumeric() => false,
-                '_' => false,
-                _ => true,
-            }
-        });
-
-        // TODO, obviously
-        let words = vec![
-            "let ",
-            "fn ",
-            "dimension ",
-            "unit ",
-            //
-            "sqrt(",
-            "sqr(",
-            "exp(",
-            "abs(",
-            "round(",
-            "sin(",
-            "atan2(",
-            "toCelsius(",
-            "toKelvin(",
-            "print(",
-            "assert_eq(",
-            //
-            "metric_prefixes",
-            "binary_prefixes",
-            "aliases",
-            "aliases_short",
-            //
-            "gravity",
-            "speed_of_light",
-            //
-            "Scalar",
-            "Length",
-            "Time",
-            "Mass",
-            //
-            "meter",
-            "second",
-            "gram",
-            //
-            "micro",
-            "milli",
-            "centi",
-            "deci",
-            "kilo",
-            "mega",
-        ];
-
-        let candidates = words.iter().filter(|w| w.starts_with(word_part));
-
-        Ok((
-            pos_word,
-            candidates
-                .map(|w| Pair {
-                    display: w.to_string(),
-                    replacement: w.to_string(),
-                })
-                .collect(),
-        ))
-    }
-}
-
 #[derive(Completer, Helper, Hinter, Validator, Highlighter)]
 struct NumbatHelper {
     #[rustyline(Completer)]