Prompt
Design APIs with appropriate parameter types, place conversion functions as trait implementations in the correct modules, and reuse existing patterns instead of creating new abstractions.
Key principles:
-
Use appropriate parameter types: Prefer
&[T]over&Vec<T>for function parameters to accept more input types and improve API flexibility. -
Place conversions as trait implementations: When creating conversion functions, implement them as traits (like
From<&str>) in the module where the target type is defined, rather than standalone functions elsewhere. -
Reuse existing patterns: Before creating new IPC messages, traits, or abstractions, check if existing patterns can be extended or reused. Avoid adding dependencies just for cleaner conversions when simple functions suffice.
-
Prefer functional patterns: Use
map(),unwrap_or_else(), and similar combinators instead of imperative if-let chains when it improves readability.
Example of good API design:
// Good: slice parameter, functional style
fn process_link_headers(link_headers: &[LinkHeader]) -> Vec<ProcessedLink> {
link_headers.iter()
.map(|header| process_header(header))
.collect()
}
// Good: trait implementation in type's module
impl From<&str> for CorsSettings {
fn from(token: &str) -> Self {
match_ignore_ascii_case! { token,
"anonymous" => CorsSettings::Anonymous,
"use-credentials" => CorsSettings::UseCredentials,
_ => CorsSettings::Anonymous,
}
}
}
This approach creates more flexible, discoverable, and maintainable APIs while avoiding unnecessary complexity.