Commit

Author:

Hash:

Timestamp:

+25 -31 +/-2 browse

Kevin Schoon [me@kevinschoon.com]

a8a2f7a6685c27323baefbcefa02e404c2423172

Thu, 24 Jul 2025 21:09:11 +0000 (3 months ago)

eliminate dyn error in Configurable trait
1diff --git a/ayllu/src/config.rs b/ayllu/src/config.rs
2index 5e15b88..78452ae 100644
3--- a/ayllu/src/config.rs
4+++ b/ayllu/src/config.rs
5 @@ -1,10 +1,9 @@
6- use std::error::Error as StdError;
7 use std::fs::metadata;
8 use std::path::Path;
9 use std::{collections::HashMap, path::PathBuf};
10 use url::Url;
11
12- use ayllu_config::{Configurable, Reader};
13+ use ayllu_config::{Configurable, Error, Reader};
14
15 use serde::{Deserialize, Serialize};
16
17 @@ -59,16 +58,6 @@ const DEFAULT_TREE_SITTER_KEYWORDS: &[&str] = &[
18 "removal",
19 ];
20
21- #[derive(thiserror::Error, Debug)]
22- pub enum Error {
23- #[error("Nix: {0}")]
24- Nix(#[from] nix::Error),
25- #[error("User {0} was not found")]
26- UserNotFound(String),
27- #[error("User {0} has invalid configuration")]
28- InvalidConfig(String),
29- }
30-
31 fn default_false() -> bool {
32 false
33 }
34 @@ -298,14 +287,16 @@ pub mod identity {
35 }
36
37 impl Configurable for Config {
38- fn validate(&mut self) -> Result<(), Box<dyn StdError>> {
39+ fn validate(&mut self) -> Result<(), Error> {
40 Ok(())
41 }
42 }
43
44 pub(crate) fn resolve(identity: &Identity) -> Result<Resolved, Error> {
45 let name = &identity.username;
46- match nix::unistd::User::from_name(&identity.username)? {
47+ match nix::unistd::User::from_name(&identity.username)
48+ .map_err(|e| Error::Initialization(e.to_string()))?
49+ {
50 Some(user) => {
51 match Reader::<Config>::load(Some(
52 user.dir.join(".config/ayllu/config.toml").as_path(),
53 @@ -322,18 +313,18 @@ pub mod identity {
54 // If the user did not specify their identity skip
55 // them entirely.
56 eprintln!("User {name} has no identity configuration, skipping",);
57- Err(Error::InvalidConfig(name.to_string()))
58+ Err(Error::Initialization(name.to_string()))
59 }
60 }
61 }
62 Err(err) => {
63 // invalid user config will just be ignored
64 eprintln!("Failed to load user {name} configuration {err}",);
65- Err(Error::InvalidConfig(name.to_string()))
66+ Err(Error::Initialization(name.to_string()))
67 }
68 }
69 }
70- None => Err(Error::UserNotFound(name.to_string())),
71+ None => Err(Error::Initialization(name.to_string())),
72 }
73 }
74 }
75 @@ -401,8 +392,9 @@ pub struct Config {
76 }
77
78 impl Configurable for Config {
79- fn validate(&mut self) -> Result<(), Box<dyn StdError>> {
80- let parsed_url = Url::parse(&self.origin)?;
81+ fn validate(&mut self) -> Result<(), Error> {
82+ let parsed_url = Url::parse(&self.origin)
83+ .map_err(|e| Error::Validation(format!("Cannot parse URL: {}: {e:?}", self.origin)))?;
84 self.domain = parsed_url.domain().map(|domain| domain.to_string());
85
86 // verify collection names are all valid
87 @@ -411,17 +403,19 @@ impl Configurable for Config {
88 .iter()
89 .find(|collection| BANNED_COLLECTION_NAMES.contains(&collection.name.as_str()))
90 {
91- return Err(format!("{} is a reserved name", collection.name)
92- .as_str()
93- .into());
94+ return Err(Error::Validation(format!(
95+ "{} is a reserved name",
96+ collection.name
97+ )));
98 };
99
100 // validate that all collection directories exist
101 for collection in self.collections.iter() {
102 if let Err(err) = metadata(collection.path.clone()) {
103- return Err(
104- format!("could not load collection {}:\n{}", collection.name, err).into(),
105- );
106+ return Err(Error::Validation(format!(
107+ "Failed to load collection {}:\n{err}",
108+ collection.name
109+ )));
110 }
111 }
112
113 @@ -431,9 +425,10 @@ impl Configurable for Config {
114 .iter()
115 .any(|theme| theme.name == self.web.default_theme)
116 {
117- return Err(
118- format!("Default theme {} is not configured", self.web.default_theme).into(),
119- );
120+ return Err(Error::Validation(format!(
121+ "Default theme is not configured: {}",
122+ self.web.default_theme
123+ )));
124 }
125
126 // resolve user collections
127 diff --git a/crates/config/src/reader.rs b/crates/config/src/reader.rs
128index 4a1feaf..b272f16 100644
129--- a/crates/config/src/reader.rs
130+++ b/crates/config/src/reader.rs
131 @@ -1,5 +1,4 @@
132 use std::env;
133- use std::error::Error as StdError;
134 use std::path::{Path, PathBuf};
135
136 use serde::de::DeserializeOwned;
137 @@ -9,12 +8,12 @@ use crate::error::Error;
138
139 pub trait Configurable {
140 /// initialize the configuration (typically set defaults)
141- fn initialize(&mut self) -> Result<(), Box<dyn StdError>> {
142+ fn initialize(&mut self) -> Result<(), Error> {
143 Ok(())
144 }
145
146 /// validate non-serialization errors
147- fn validate(&mut self) -> Result<(), Box<dyn StdError>> {
148+ fn validate(&mut self) -> Result<(), Error> {
149 Ok(())
150 }
151 }