1use clap::{ArgEnum, Parser};
19use std::{
20 convert::TryFrom,
21 ffi::OsString,
22 io::{Error as IoError, ErrorKind},
23};
24
25#[derive(Debug, Clone, Copy, PartialEq, ArgEnum)]
26pub enum Framework {
27 Baremetal,
28 EspIdf,
29}
30
31impl Framework {
32 pub fn from_target<S: AsRef<str>>(target: S) -> Result<Self, IoError> {
33 let target = target.as_ref();
34 if target.ends_with("-espidf") {
35 Ok(Framework::EspIdf)
36 } else if target.ends_with("-none-elf") {
37 Ok(Framework::Baremetal)
38 } else {
39 Err(IoError::new(
40 ErrorKind::InvalidInput,
41 format!("Can't figure out framework from target '{}'", target),
42 ))
43 }
44 }
45}
46
47impl TryFrom<&str> for Framework {
48 type Error = IoError;
49 fn try_from(value: &str) -> Result<Self, Self::Error> {
50 match value {
51 "baremetal" => Ok(Framework::Baremetal),
52 "esp-idf" | "espidf" => Ok(Framework::EspIdf),
53 _ => Err(IoError::new(
54 ErrorKind::InvalidInput,
55 format!("'{}' is not a valid framework", value),
56 )),
57 }
58 }
59}
60
61impl Default for Framework {
62 fn default() -> Self {
63 Framework::Baremetal
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, ArgEnum)]
68pub enum Chip {
69 ESP32,
70 ESP32S2,
71 ESP8266,
72 ESP32C3,
73}
74
75impl Chip {
76 pub fn from_target<S: AsRef<str>>(target: S) -> Result<Chip, IoError> {
77 let target = target.as_ref();
78 if target.contains("-esp32-") {
79 Ok(Chip::ESP32)
80 } else if target.contains("-esp32s2-") {
81 Ok(Chip::ESP32S2)
82 } else if target.contains("-esp8266-") {
83 Ok(Chip::ESP8266)
84 } else {
85 Err(IoError::new(
86 ErrorKind::InvalidInput,
87 format!(
88 "Can't figure out chip from target '{}'; try specifying the --chip option",
89 target
90 ),
91 ))
92 }
93 }
94}
95
96impl Chip {
97 pub fn target(&self, framework: Framework) -> String {
98 let mut target = String::new();
99 target.push_str(match self {
100 Chip::ESP32C3 => "riscv32imc-",
101 _ => "xtensa-",
102 });
103 target.push_str(match self {
104 Chip::ESP32 => "esp32-",
105 Chip::ESP32S2 => "esp32s2-",
106 Chip::ESP8266 => "esp8266-",
107 Chip::ESP32C3 => match framework {
108 Framework::Baremetal => "unknown-",
109 Framework::EspIdf => "esp-",
110 },
111 });
112 target.push_str(match framework {
113 Framework::Baremetal => "none-elf",
114 Framework::EspIdf => "espidf",
115 });
116 target
117 }
118}
119
120impl TryFrom<&str> for Chip {
121 type Error = IoError;
122 fn try_from(value: &str) -> Result<Self, Self::Error> {
123 match value {
124 "esp32" => Ok(Chip::ESP32),
125 "esp32c3" => Ok(Chip::ESP32C3),
126 "esp8266" => Ok(Chip::ESP8266),
127 _ => Err(IoError::new(
128 ErrorKind::InvalidInput,
129 format!("'{}' is not a valid chip", value),
130 )),
131 }
132 }
133}
134
135impl Default for Chip {
136 fn default() -> Self {
137 Chip::ESP32
138 }
139}
140
141#[derive(Parser, Debug)]
142#[clap(author, version, about)]
143pub struct AppArgs {
144 #[clap(short, long)]
146 pub reset: bool,
147
148 #[clap(long, conflicts_with("reset"))]
150 pub no_reset: bool,
151
152 #[clap(long, short, default_value = "115200", name = "BAUD")]
154 pub speed: usize,
155
156 #[clap(long, short, name = "BINARY")]
158 pub bin: Option<OsString>,
159
160 #[clap(name = "SERIAL_DEVICE")]
162 pub serial: String,
163}