args.rs: implemented From<PackageParseError> for (String, u32)
This commit is contained in:
parent
875290a75c
commit
ba726358b4
11
src/args.rs
11
src/args.rs
|
@ -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)
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue