Design API parameters using specific, intention-revealing types rather than generic or ambiguous ones. This improves code readability, prevents misuse, and makes the API's behavior self-documenting.
Design API parameters using specific, intention-revealing types rather than generic or ambiguous ones. This improves code readability, prevents misuse, and makes the API’s behavior self-documenting.
Key principles:
Option<T>
instead of default values when a parameter is truly optionalExamples of improvements:
Replace default values with Option when appropriate:
// Before: Unclear if version is required
struct Version {
#[arg(default_value = "0.0.0")]
pub version: SemverVersion,
}
// After: Clear that version is optional
struct Version {
pub version: Option<SemverVersion>,
}
Replace multiple bools with enum:
// Before: Multiple related flags
pub bump: bool,
pub bump_minor: bool,
pub bump_major: bool,
// After: Single enum parameter
pub bump: Option<BumpType>, // where BumpType = { Patch, Minor, Major }
Use specific parameters over generic ones:
// Before: Generic but unclear
fn needs_recompile(lib_path: &Path, parser_c_path: &Path, scanner_path: &Option<PathBuf>, external_files_paths: &[PathBuf])
// After: Generalized and clear
fn needs_recompile(checking_paths: &[Path])
This approach makes function signatures self-documenting and reduces the cognitive load on API consumers by making valid usage patterns explicit in the type system.
Enter the URL of a public GitHub repository