Trait erg_common::traits::Runnable
source · pub trait Runnable: Sized + Default {
type Err: ErrorDisplay;
type Errs: MultiErrorDisplay<Self::Err>;
const NAME: &'static str;
Show 16 methods
fn new(cfg: ErgConfig) -> Self;
fn cfg(&self) -> &ErgConfig;
fn cfg_mut(&mut self) -> &mut ErgConfig;
fn finish(&mut self);
fn initialize(&mut self);
fn clear(&mut self);
fn eval(&mut self, src: String) -> Result<String, Self::Errs>;
fn exec(&mut self) -> Result<i32, Self::Errs>;
fn input(&self) -> &Input { ... }
fn set_input(&mut self, input: Input) { ... }
fn start_message(&self) -> String { ... }
fn ps1(&self) -> String { ... }
fn ps2(&self) -> String { ... }
fn quit(&mut self, code: i32) -> ! { ... }
fn quit_successfully(&mut self, output: BufWriter<StdoutLock<'_>>) -> ! { ... }
fn run(cfg: ErgConfig) { ... }
}
Expand description
This trait implements REPL (Read-Eval-Print-Loop) automatically
The exec
method is called for file input, etc.
Required Associated Types§
type Err: ErrorDisplay
type Errs: MultiErrorDisplay<Self::Err>
Required Associated Constants§
Required Methods§
fn new(cfg: ErgConfig) -> Self
fn cfg(&self) -> &ErgConfig
fn cfg_mut(&mut self) -> &mut ErgConfig
fn finish(&mut self)
sourcefn initialize(&mut self)
fn initialize(&mut self)
Erase all but immutable information.
fn eval(&mut self, src: String) -> Result<String, Self::Errs>
fn exec(&mut self) -> Result<i32, Self::Errs>
Provided Methods§
sourcefn input(&self) -> &Input
fn input(&self) -> &Input
Examples found in repository?
traits.rs (line 434)
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
fn run(cfg: ErgConfig) {
let quiet_repl = cfg.quiet_repl;
let mut instance = Self::new(cfg);
let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
Input::REPL => {
let output = stdout();
let mut output = BufWriter::new(output.lock());
if !quiet_repl {
log!(info_f output, "The REPL has started.\n");
output
.write_all(instance.start_message().as_bytes())
.unwrap();
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
let mut in_block = false;
let mut lines = String::new();
loop {
let line = chomp(&instance.input().read());
match &line[..] {
":quit" | ":exit" => {
instance.quit_successfully(output);
}
":clear" => {
output.write_all("\x1b[2J\x1b[1;1H".as_bytes()).unwrap();
output.flush().unwrap();
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
continue;
}
_ => {}
}
let line = if let Some(comment_start) = line.find('#') {
&line[..comment_start]
} else {
&line[..]
};
lines.push_str(line);
if in_block {
if is_in_the_expected_block(line, &lines, &mut in_block) {
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
} else if expect_block(line) {
in_block = true;
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
match instance.eval(mem::take(&mut lines)) {
Ok(out) => {
output.write_all((out + "\n").as_bytes()).unwrap();
output.flush().unwrap();
}
Err(errs) => {
if errs
.first()
.map(|e| e.core().kind == ErrorKind::SystemExit)
.unwrap_or(false)
{
instance.quit_successfully(output);
}
errs.fmt_all_stderr();
}
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
}
}
Input::Dummy => switch_unreachable!(),
};
if let Err(e) = res {
e.fmt_all_stderr();
instance.quit(1);
}
}
fn set_input(&mut self, input: Input)
sourcefn start_message(&self) -> String
fn start_message(&self) -> String
Examples found in repository?
traits.rs (line 442)
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
fn run(cfg: ErgConfig) {
let quiet_repl = cfg.quiet_repl;
let mut instance = Self::new(cfg);
let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
Input::REPL => {
let output = stdout();
let mut output = BufWriter::new(output.lock());
if !quiet_repl {
log!(info_f output, "The REPL has started.\n");
output
.write_all(instance.start_message().as_bytes())
.unwrap();
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
let mut in_block = false;
let mut lines = String::new();
loop {
let line = chomp(&instance.input().read());
match &line[..] {
":quit" | ":exit" => {
instance.quit_successfully(output);
}
":clear" => {
output.write_all("\x1b[2J\x1b[1;1H".as_bytes()).unwrap();
output.flush().unwrap();
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
continue;
}
_ => {}
}
let line = if let Some(comment_start) = line.find('#') {
&line[..comment_start]
} else {
&line[..]
};
lines.push_str(line);
if in_block {
if is_in_the_expected_block(line, &lines, &mut in_block) {
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
} else if expect_block(line) {
in_block = true;
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
match instance.eval(mem::take(&mut lines)) {
Ok(out) => {
output.write_all((out + "\n").as_bytes()).unwrap();
output.flush().unwrap();
}
Err(errs) => {
if errs
.first()
.map(|e| e.core().kind == ErrorKind::SystemExit)
.unwrap_or(false)
{
instance.quit_successfully(output);
}
errs.fmt_all_stderr();
}
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
}
}
Input::Dummy => switch_unreachable!(),
};
if let Err(e) = res {
e.fmt_all_stderr();
instance.quit(1);
}
}
sourcefn ps1(&self) -> String
fn ps1(&self) -> String
Examples found in repository?
traits.rs (line 445)
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
fn run(cfg: ErgConfig) {
let quiet_repl = cfg.quiet_repl;
let mut instance = Self::new(cfg);
let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
Input::REPL => {
let output = stdout();
let mut output = BufWriter::new(output.lock());
if !quiet_repl {
log!(info_f output, "The REPL has started.\n");
output
.write_all(instance.start_message().as_bytes())
.unwrap();
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
let mut in_block = false;
let mut lines = String::new();
loop {
let line = chomp(&instance.input().read());
match &line[..] {
":quit" | ":exit" => {
instance.quit_successfully(output);
}
":clear" => {
output.write_all("\x1b[2J\x1b[1;1H".as_bytes()).unwrap();
output.flush().unwrap();
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
continue;
}
_ => {}
}
let line = if let Some(comment_start) = line.find('#') {
&line[..comment_start]
} else {
&line[..]
};
lines.push_str(line);
if in_block {
if is_in_the_expected_block(line, &lines, &mut in_block) {
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
} else if expect_block(line) {
in_block = true;
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
match instance.eval(mem::take(&mut lines)) {
Ok(out) => {
output.write_all((out + "\n").as_bytes()).unwrap();
output.flush().unwrap();
}
Err(errs) => {
if errs
.first()
.map(|e| e.core().kind == ErrorKind::SystemExit)
.unwrap_or(false)
{
instance.quit_successfully(output);
}
errs.fmt_all_stderr();
}
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
}
}
Input::Dummy => switch_unreachable!(),
};
if let Err(e) = res {
e.fmt_all_stderr();
instance.quit(1);
}
}
sourcefn ps2(&self) -> String
fn ps2(&self) -> String
Examples found in repository?
traits.rs (line 475)
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
fn run(cfg: ErgConfig) {
let quiet_repl = cfg.quiet_repl;
let mut instance = Self::new(cfg);
let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
Input::REPL => {
let output = stdout();
let mut output = BufWriter::new(output.lock());
if !quiet_repl {
log!(info_f output, "The REPL has started.\n");
output
.write_all(instance.start_message().as_bytes())
.unwrap();
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
let mut in_block = false;
let mut lines = String::new();
loop {
let line = chomp(&instance.input().read());
match &line[..] {
":quit" | ":exit" => {
instance.quit_successfully(output);
}
":clear" => {
output.write_all("\x1b[2J\x1b[1;1H".as_bytes()).unwrap();
output.flush().unwrap();
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
continue;
}
_ => {}
}
let line = if let Some(comment_start) = line.find('#') {
&line[..comment_start]
} else {
&line[..]
};
lines.push_str(line);
if in_block {
if is_in_the_expected_block(line, &lines, &mut in_block) {
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
} else if expect_block(line) {
in_block = true;
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
match instance.eval(mem::take(&mut lines)) {
Ok(out) => {
output.write_all((out + "\n").as_bytes()).unwrap();
output.flush().unwrap();
}
Err(errs) => {
if errs
.first()
.map(|e| e.core().kind == ErrorKind::SystemExit)
.unwrap_or(false)
{
instance.quit_successfully(output);
}
errs.fmt_all_stderr();
}
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
}
}
Input::Dummy => switch_unreachable!(),
};
if let Err(e) = res {
e.fmt_all_stderr();
instance.quit(1);
}
}
sourcefn quit(&mut self, code: i32) -> !
fn quit(&mut self, code: i32) -> !
Examples found in repository?
traits.rs (line 512)
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
fn run(cfg: ErgConfig) {
let quiet_repl = cfg.quiet_repl;
let mut instance = Self::new(cfg);
let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
Input::REPL => {
let output = stdout();
let mut output = BufWriter::new(output.lock());
if !quiet_repl {
log!(info_f output, "The REPL has started.\n");
output
.write_all(instance.start_message().as_bytes())
.unwrap();
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
let mut in_block = false;
let mut lines = String::new();
loop {
let line = chomp(&instance.input().read());
match &line[..] {
":quit" | ":exit" => {
instance.quit_successfully(output);
}
":clear" => {
output.write_all("\x1b[2J\x1b[1;1H".as_bytes()).unwrap();
output.flush().unwrap();
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
continue;
}
_ => {}
}
let line = if let Some(comment_start) = line.find('#') {
&line[..comment_start]
} else {
&line[..]
};
lines.push_str(line);
if in_block {
if is_in_the_expected_block(line, &lines, &mut in_block) {
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
} else if expect_block(line) {
in_block = true;
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
match instance.eval(mem::take(&mut lines)) {
Ok(out) => {
output.write_all((out + "\n").as_bytes()).unwrap();
output.flush().unwrap();
}
Err(errs) => {
if errs
.first()
.map(|e| e.core().kind == ErrorKind::SystemExit)
.unwrap_or(false)
{
instance.quit_successfully(output);
}
errs.fmt_all_stderr();
}
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
}
}
Input::Dummy => switch_unreachable!(),
};
if let Err(e) = res {
e.fmt_all_stderr();
instance.quit(1);
}
}
sourcefn quit_successfully(&mut self, output: BufWriter<StdoutLock<'_>>) -> !
fn quit_successfully(&mut self, output: BufWriter<StdoutLock<'_>>) -> !
Examples found in repository?
traits.rs (line 453)
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
fn run(cfg: ErgConfig) {
let quiet_repl = cfg.quiet_repl;
let mut instance = Self::new(cfg);
let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
Input::REPL => {
let output = stdout();
let mut output = BufWriter::new(output.lock());
if !quiet_repl {
log!(info_f output, "The REPL has started.\n");
output
.write_all(instance.start_message().as_bytes())
.unwrap();
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
let mut in_block = false;
let mut lines = String::new();
loop {
let line = chomp(&instance.input().read());
match &line[..] {
":quit" | ":exit" => {
instance.quit_successfully(output);
}
":clear" => {
output.write_all("\x1b[2J\x1b[1;1H".as_bytes()).unwrap();
output.flush().unwrap();
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
continue;
}
_ => {}
}
let line = if let Some(comment_start) = line.find('#') {
&line[..comment_start]
} else {
&line[..]
};
lines.push_str(line);
if in_block {
if is_in_the_expected_block(line, &lines, &mut in_block) {
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
} else if expect_block(line) {
in_block = true;
lines += "\n";
output.write_all(instance.ps2().as_bytes()).unwrap();
output.flush().unwrap();
continue;
}
match instance.eval(mem::take(&mut lines)) {
Ok(out) => {
output.write_all((out + "\n").as_bytes()).unwrap();
output.flush().unwrap();
}
Err(errs) => {
if errs
.first()
.map(|e| e.core().kind == ErrorKind::SystemExit)
.unwrap_or(false)
{
instance.quit_successfully(output);
}
errs.fmt_all_stderr();
}
}
output.write_all(instance.ps1().as_bytes()).unwrap();
output.flush().unwrap();
instance.clear();
}
}
Input::Dummy => switch_unreachable!(),
};
if let Err(e) = res {
e.fmt_all_stderr();
instance.quit(1);
}
}