pub trait TryNew {
type Error;
type Args;
// Required method
fn try_new(args: Self::Args) -> Result<Self, Self::Error>
where Self: Sized;
}Expand description
Trait for fallible construction with validation.
Implement this trait when:
- Construction requires validation that may fail
- You are NOT converting from another type (use
TryFrominstead) - A plain
new()cannot guarantee success
§Naming Convention
Types implementing TryNew should NOT have a plain new() method
that performs the same validation. The try_ prefix makes fallibility
explicit at the call site.
§Associated Types
Error: The error type returned when validation failsArgs: The arguments required for construction (can be a tuple)
§Implementation Guidelines
- Document invariants: Explain what validation is performed
- Use specific errors: Return meaningful error types, not
String - Keep validation pure: Don’t perform side effects in
try_new - Consider
Argstype: Use tuples for multiple arguments
§Example: Single Argument
use orcs_types::TryNew;
struct PositiveInt(i32);
#[derive(Debug)]
struct NotPositiveError;
impl TryNew for PositiveInt {
type Error = NotPositiveError;
type Args = i32;
fn try_new(value: i32) -> Result<Self, Self::Error> {
if value <= 0 {
return Err(NotPositiveError);
}
Ok(PositiveInt(value))
}
}§Example: Multiple Arguments (Tuple)
use orcs_types::TryNew;
struct Range {
start: u32,
end: u32,
}
#[derive(Debug)]
struct InvalidRangeError;
impl TryNew for Range {
type Error = InvalidRangeError;
type Args = (u32, u32);
fn try_new((start, end): (u32, u32)) -> Result<Self, Self::Error> {
if start >= end {
return Err(InvalidRangeError);
}
Ok(Range { start, end })
}
}
// Usage
let range = Range::try_new((1, 10));
assert!(range.is_ok());§Example: Config Struct Argument
use orcs_types::TryNew;
struct Server {
host: String,
port: u16,
}
struct ServerConfig {
host: String,
port: u16,
}
#[derive(Debug)]
enum ServerError {
EmptyHost,
InvalidPort,
}
impl TryNew for Server {
type Error = ServerError;
type Args = ServerConfig;
fn try_new(config: ServerConfig) -> Result<Self, Self::Error> {
if config.host.is_empty() {
return Err(ServerError::EmptyHost);
}
if config.port == 0 {
return Err(ServerError::InvalidPort);
}
Ok(Server {
host: config.host,
port: config.port,
})
}
}Required Associated Types§
Required Methods§
Sourcefn try_new(args: Self::Args) -> Result<Self, Self::Error>where
Self: Sized,
fn try_new(args: Self::Args) -> Result<Self, Self::Error>where
Self: Sized,
Attempts to create a new instance.
§Errors
Returns Self::Error if validation fails. The error should
contain enough information to understand why construction failed.
§Example
use orcs_types::TryNew;
struct Bounded(u8);
#[derive(Debug)]
struct OutOfBounds;
impl TryNew for Bounded {
type Error = OutOfBounds;
type Args = u8;
fn try_new(value: u8) -> Result<Self, Self::Error> {
if value > 100 {
return Err(OutOfBounds);
}
Ok(Bounded(value))
}
}
assert!(Bounded::try_new(50).is_ok());
assert!(Bounded::try_new(150).is_err());