Coverage for src/monadc/result/result.py: 63%
62 statements
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-19 20:24 -0700
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-19 20:24 -0700
1from typing import TypeVar, Generic, Callable, Union, Any, Optional
3T = TypeVar('T') # Ok type (success/value)
4E = TypeVar('E') # Err type (error/failure)
5U = TypeVar('U') # Generic result type
7class Result(Generic[T, E]):
8 """
9 Rust-inspired Result monad for representing computations that can succeed or fail.
11 Result[T, E] represents a value that can be either:
12 - Ok[T]: A successful value of type T
13 - Err[E]: An error value of type E
15 This follows Rust conventions where Ok represents success and Err represents failure.
16 """
18 _UNSET = object() # Sentinel value to distinguish from None
20 def __new__(cls, ok_value: Any = _UNSET, err_value: Any = _UNSET) -> 'Result[T, E]':
21 """Factory constructor for Result. Prefer explicit Ok()/Err() construction."""
22 if cls is not Result:
23 # Direct subclass instantiation (Ok, Err)
24 return super().__new__(cls)
26 if ok_value is not cls._UNSET and err_value is not cls._UNSET:
27 raise ValueError("Cannot specify both ok_value and err_value")
29 if ok_value is not cls._UNSET:
30 from .ok import Ok
31 return Ok(ok_value)
32 elif err_value is not cls._UNSET:
33 from .err import Err
34 return Err(err_value)
35 else:
36 raise ValueError("Must specify either ok_value or err_value")
38 # Type checking methods
39 def is_ok(self) -> bool:
40 """Returns True if this Result is an Ok, False otherwise."""
41 raise NotImplementedError("Use Ok or Err, not Result directly")
43 def is_err(self) -> bool:
44 """Returns True if this Result is an Err, False otherwise."""
45 raise NotImplementedError("Use Ok or Err, not Result directly")
47 # Value extraction (Rust-style)
48 def ok(self) -> 'Any': # Returns Option[T]
49 """Get the ok value as Option - Some(value) if Ok, Nil() if Err."""
50 raise NotImplementedError("Use Ok or Err, not Result directly")
52 def err(self) -> 'Any': # Returns Option[E]
53 """Get the err value as Option - Some(error) if Err, Nil() if Ok."""
54 raise NotImplementedError("Use Ok or Err, not Result directly")
56 def unwrap(self) -> T:
57 """Get the ok value. Panics (raises exception) if this is an Err."""
58 raise NotImplementedError("Use Ok or Err, not Result directly")
60 def unwrap_err(self) -> E:
61 """Get the err value. Panics (raises exception) if this is an Ok."""
62 raise NotImplementedError("Use Ok or Err, not Result directly")
64 def unwrap_or(self, default: T) -> T:
65 """Get the ok value or return default if this is an Err."""
66 raise NotImplementedError("Use Ok or Err, not Result directly")
68 def unwrap_or_else(self, func: Callable[[E], T]) -> T:
69 """Get the ok value or compute default from error if this is an Err."""
70 raise NotImplementedError("Use Ok or Err, not Result directly")
72 # Transformations (Ok-biased)
73 def map(self, func: Callable[[T], U]) -> 'Result[U, E]':
74 """Transform the Ok value if present, otherwise return unchanged Err."""
75 raise NotImplementedError("Use Ok or Err, not Result directly")
77 def map_err(self, func: Callable[[E], U]) -> 'Result[T, U]':
78 """Transform the Err value if present, otherwise return unchanged Ok."""
79 raise NotImplementedError("Use Ok or Err, not Result directly")
81 def map_or(self, default: U, func: Callable[[T], U]) -> U:
82 """Apply func to Ok value or return default if Err."""
83 raise NotImplementedError("Use Ok or Err, not Result directly")
85 def map_or_else(self, default_func: Callable[[E], U], func: Callable[[T], U]) -> U:
86 """Apply func to Ok value or call default_func with Err value."""
87 raise NotImplementedError("Use Ok or Err, not Result directly")
89 def and_then(self, func: Callable[[T], 'Result[U, E]']) -> 'Result[U, E]':
90 """Transform Ok value to Result if present, otherwise return unchanged Err."""
91 raise NotImplementedError("Use Ok or Err, not Result directly")
93 def or_else(self, func: Callable[[E], 'Result[T, U]']) -> 'Result[T, U]':
94 """Transform Err value to Result if present, otherwise return unchanged Ok."""
95 raise NotImplementedError("Use Ok or Err, not Result directly")
97 def flatten(self) -> 'Result[Any, E]':
98 """Flatten Result[Result[T, E], E] to Result[T, E]."""
99 raise NotImplementedError("Use Ok or Err, not Result directly")
101 def transpose(self) -> 'Any': # Returns Option[Result[T, E]]
102 """Transpose Result[Option[T], E] to Option[Result[T, E]]."""
103 raise NotImplementedError("Use Ok or Err, not Result directly")
105 # Logical operations
106 def and_(self, other: 'Result[U, E]') -> 'Result[U, E]':
107 """Return other if self is Ok, otherwise return self."""
108 raise NotImplementedError("Use Ok or Err, not Result directly")
110 def or_(self, other: 'Result[T, U]') -> 'Result[T, U]':
111 """Return self if self is Ok, otherwise return other."""
112 raise NotImplementedError("Use Ok or Err, not Result directly")
114 # Inspection
115 def inspect(self, func: Callable[[T], Any]) -> 'Result[T, E]':
116 """Call func with the Ok value if present, return self unchanged."""
117 raise NotImplementedError("Use Ok or Err, not Result directly")
119 def inspect_err(self, func: Callable[[E], Any]) -> 'Result[T, E]':
120 """Call func with the Err value if present, return self unchanged."""
121 raise NotImplementedError("Use Ok or Err, not Result directly")
123 # Conversions
124 def to_option(self) -> 'Any': # Returns Option[T]
125 """Convert Result to Option, losing error information."""
126 raise NotImplementedError("Use Ok or Err, not Result directly")
128 def to_try(self) -> 'Any': # Returns Try[T]
129 """Convert Result to Try, converting Err to Failure."""
130 raise NotImplementedError("Use Ok or Err, not Result directly")