blob: 8aec3ff55e4b1717bb637fa235562e8c434b1576 [file] [log] [blame]
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Infrequently used shell commands
extern crate alloc;
use crate::CmdFn;
use crate::CommandError;
use crate::HashMap;
use alloc::vec::Vec;
use core::fmt::Write;
use cantrip_io as io;
pub fn add_cmds(cmds: &mut HashMap<&str, CmdFn>) {
cmds.extend([
("add", add_command as CmdFn),
("echo", echo_command as CmdFn),
("clear", clear_command as CmdFn),
("rz", rz_command as CmdFn),
]);
}
/// Implements a binary float addition command.
///
/// This is a toy to demonstrate that the CLI can operate on some very basic
/// dynamic input and that the Rust runtime provides floating point arithmetic
/// on integer-only hardware. It is also a prototype example of "command taking
/// arguments." It should be removed once actually useful system control
/// commands are implemented and done cribbing from it.
fn add_command(
args: &mut dyn Iterator<Item = &str>,
_input: &mut dyn io::BufRead,
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
let x_str = args.next().ok_or(CommandError::BadArgs)?;
let x = x_str.parse::<f32>()?;
let y_str = args.next().ok_or(CommandError::BadArgs)?;
let y = y_str.parse::<f32>()?;
return Ok(writeln!(output, "{}", x + y)?);
}
/// Implements a command that outputs the ANSI "clear console" sequence.
fn clear_command(
_args: &mut dyn Iterator<Item = &str>,
_input: &mut dyn io::BufRead,
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
Ok(output.write_str("\x1b\x63")?)
}
/// Implements an "echo" command which writes its arguments to output.
fn echo_command(
args: &mut dyn Iterator<Item = &str>,
_input: &mut dyn io::BufRead,
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
let value = args.collect::<Vec<&str>>().join(" ");
Ok(writeln!(output, "{}", &value)?)
}
/// Implements a command to receive a blob using ZMODEM.
fn rz_command(
_args: &mut dyn Iterator<Item = &str>,
input: &mut dyn io::BufRead,
mut output: &mut dyn io::Write,
) -> Result<(), CommandError> {
let upload = crate::rz::rz(input, &mut output)?;
writeln!(
output,
"size: {}, crc32: {}",
upload.len(),
hex::encode(upload.crc32().to_be_bytes())
)?;
Ok(())
}