use clap::{ArgEnum, Parser};
use std::{
convert::TryFrom,
ffi::OsString,
io::{Error as IoError, ErrorKind},
};
#[derive(Debug, Clone, Copy, PartialEq, ArgEnum)]
pub enum Framework {
Baremetal,
EspIdf,
}
impl Framework {
pub fn from_target<S: AsRef<str>>(target: S) -> Result<Self, IoError> {
let target = target.as_ref();
if target.ends_with("-espidf") {
Ok(Framework::EspIdf)
} else if target.ends_with("-none-elf") {
Ok(Framework::Baremetal)
} else {
Err(IoError::new(
ErrorKind::InvalidInput,
format!("Can't figure out framework from target '{}'", target),
))
}
}
}
impl TryFrom<&str> for Framework {
type Error = IoError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"baremetal" => Ok(Framework::Baremetal),
"esp-idf" | "espidf" => Ok(Framework::EspIdf),
_ => Err(IoError::new(
ErrorKind::InvalidInput,
format!("'{}' is not a valid framework", value),
)),
}
}
}
impl Default for Framework {
fn default() -> Self {
Framework::Baremetal
}
}
#[derive(Debug, Clone, Copy, PartialEq, ArgEnum)]
pub enum Chip {
ESP32,
ESP32S2,
ESP8266,
ESP32C3,
}
impl Chip {
pub fn from_target<S: AsRef<str>>(target: S) -> Result<Chip, IoError> {
let target = target.as_ref();
if target.contains("-esp32-") {
Ok(Chip::ESP32)
} else if target.contains("-esp32s2-") {
Ok(Chip::ESP32S2)
} else if target.contains("-esp8266-") {
Ok(Chip::ESP8266)
} else {
Err(IoError::new(
ErrorKind::InvalidInput,
format!(
"Can't figure out chip from target '{}'; try specifying the --chip option",
target
),
))
}
}
}
impl Chip {
pub fn target(&self, framework: Framework) -> String {
let mut target = String::new();
target.push_str(match self {
Chip::ESP32C3 => "riscv32imc-",
_ => "xtensa-",
});
target.push_str(match self {
Chip::ESP32 => "esp32-",
Chip::ESP32S2 => "esp32s2-",
Chip::ESP8266 => "esp8266-",
Chip::ESP32C3 => match framework {
Framework::Baremetal => "unknown-",
Framework::EspIdf => "esp-",
},
});
target.push_str(match framework {
Framework::Baremetal => "none-elf",
Framework::EspIdf => "espidf",
});
target
}
}
impl TryFrom<&str> for Chip {
type Error = IoError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"esp32" => Ok(Chip::ESP32),
"esp32c3" => Ok(Chip::ESP32C3),
"esp8266" => Ok(Chip::ESP8266),
_ => Err(IoError::new(
ErrorKind::InvalidInput,
format!("'{}' is not a valid chip", value),
)),
}
}
}
impl Default for Chip {
fn default() -> Self {
Chip::ESP32
}
}
#[derive(Parser, Debug)]
#[clap(author, version, about)]
pub struct AppArgs {
#[clap(short, long)]
pub reset: bool,
#[clap(long, conflicts_with("reset"))]
pub no_reset: bool,
#[clap(long, short, default_value = "115200", name = "BAUD")]
pub speed: usize,
#[clap(long, short, name = "BINARY")]
pub bin: Option<OsString>,
#[clap(name = "SERIAL_DEVICE")]
pub serial: String,
}