args.rs: implemented From<PackageParseError> for (String, u32)

This commit is contained in:
Emma Tebibyte 2023-03-27 00:32:27 -04:00
parent 875290a75c
commit ba726358b4
Signed by: emma
GPG Key ID: 6D661C738815E7DD
4 changed files with 12 additions and 63 deletions

View File

@ -24,6 +24,7 @@ use core::{
};
pub use arg::Args;
use yacexits::EX_DATAERR;
#[derive(Args, Debug)]
pub struct Arguments {
@ -160,6 +161,14 @@ impl std::default::Default for PackageType { //TODO: Actually implement Default
}
}
impl From<PackageParseError> for (String, u32) {
fn from(error: PackageParseError) -> Self {
match error {
PackageParseError::Invalid(err) => (err, EX_DATAERR),
}
}
}
impl FromStr for PackageType {
type Err = PackageParseError;
fn from_str(s: &str) -> Result<PackageType, PackageParseError> {
@ -167,7 +176,7 @@ impl FromStr for PackageType {
if pieces.len() > 2 || pieces.len() == 1 {
return Err(PackageParseError::Invalid(
format!("{}: Invalid package name.", s)
format!("{}: Invalid package type.", s)
));
}

View File

@ -146,55 +146,3 @@ async fn select_from_results(
Ok(selected)
}
// TODO implement enum for more graceful exiting
async fn select_from_results(
_ctx: &AppContext,
response: &SearchResponse,
) -> anyhow::Result<Vec<usize>> {
let input: String = dialoguer::Input::new()
.with_prompt("Mods to install (eg: 1 2 3-5)")
.interact_text()?;
let mut selected: Vec<usize> = Vec::new();
for token in input.split(" ") {
let terms: Vec<&str> = token.split("-").collect();
match terms.len() {
1 => selected.push(terms[0].parse().expect("Token must be an integer")),
2 => {
let terms: Vec<usize> = terms
.iter()
.map(|term| term.parse().expect("Term must be an integer"))
.collect();
let from = terms[0];
let to = terms[1];
for index in from..=to {
selected.push(index);
}
}
_ => panic!("Invalid selection token {}", token),
}
}
selected.dedup();
let selected = selected
.iter()
.map(|index| {
if *index < 1 || *index > response.hits.len() {
// TODO return useful error instead of panicking
panic!("Index {} is out of bounds", index);
}
// input is indexed from 1, but results are indexed from 0
let index = index - 1;
index
})
.collect();
Ok(selected)
}

View File

@ -19,8 +19,6 @@
* Hopper. If not, see <https://www.gnu.org/licenses/>.
*/
use crate::HopError;
use std::{
fs::File,
io::{ Read, self },
@ -56,6 +54,7 @@ pub enum ConfigError {
impl From<ConfigError> for (String, u32) {
fn from(error: ConfigError) -> Self {
let (message, code) = match error {
// TODO: More precise matching inside these arms
ConfigError::CreateError(_) => {
("Unable to create configuration file.", EX_UNAVAILABLE)
},

View File

@ -24,6 +24,7 @@ pub struct HopError {
pub message: String,
}
// TODO: More granular matching here
impl From<arg::ParseKind<'_>> for HopError {
fn from(_: arg::ParseKind) -> Self {
let message = format!(
@ -40,14 +41,6 @@ impl From<arg::ParseKind<'_>> for HopError {
}
}
impl From<xdg::BaseDirectoriesError> for HopError {
fn from(err: xdg::BaseDirectoriesError) -> Self {
let message = format!("{}: Unable to open configuration file", err);
Self { message, code: EX_UNAVAILABLE }
}
}
impl From<HopError> for (String, u32) {
fn from(err: HopError) -> Self {
(err.message, err.code)