espmonitor/
types.rs

1// Copyright 2021 Brian J. Tarricone <brian@tarricone.org>
2//
3// This file is part of ESPMonitor.
4//
5// ESPMonitor is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// ESPMonitor is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with ESPMonitor.  If not, see <https://www.gnu.org/licenses/>.
17
18use 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    /// Reset the chip on start [default]
145    #[clap(short, long)]
146    pub reset: bool,
147
148    /// Do not reset the chip on start
149    #[clap(long, conflicts_with("reset"))]
150    pub no_reset: bool,
151
152    /// Baud rate of serial device
153    #[clap(long, short, default_value = "115200", name = "BAUD")]
154    pub speed: usize,
155
156    /// Path to executable matching what is on the device
157    #[clap(long, short, name = "BINARY")]
158    pub bin: Option<OsString>,
159
160    /// Path to the serial device
161    #[clap(name = "SERIAL_DEVICE")]
162    pub serial: String,
163}