When designing APIs, prioritize flexibility, ergonomics, and intuitiveness to create better user experiences. APIs should accept the most general parameter types appropriate for the functionality, handle edge cases gracefully, and provide methods that align with user expectations.
When designing APIs, prioritize flexibility, ergonomics, and intuitiveness to create better user experiences. APIs should accept the most general parameter types appropriate for the functionality, handle edge cases gracefully, and provide methods that align with user expectations.
Key practices:
impl Into<String>
instead of String
)Example of flexible parameter types:
// Instead of this:
pub fn name(&mut self, name: String) -> &mut Self {
// implementation
}
// Prefer this:
pub fn name(&mut self, name: impl Into<String>) -> &mut Self {
let name = name.into();
// implementation
}
Example of intuitive async API design:
// Instead of requiring separate calls:
pub async fn wait(&self) {
// implementation that just waits
}
pub fn get(&self) -> Option<&T> {
// implementation
}
// Consider this more ergonomic design:
pub async fn wait(&self) -> &T {
// implementation that returns the value directly
}
Example of providing inspection methods:
impl<T> Receiver<T> {
/// Checks if this receiver is finished.
///
/// Returns true if this receiver has been polled and yielded a result.
pub fn is_finished(&self) -> bool {
self.inner.is_none()
}
// Additional inspection methods to query other aspects of state
}
Enter the URL of a public GitHub repository