-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #38 from PickwickSoft/feature/add-internal-optiona…
…l-implementation Feature/add internal optional implementation
- Loading branch information
Showing
10 changed files
with
300 additions
and
45 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
class Optional: | ||
""" | ||
A container object which may or may not contain a non-none value. | ||
If a value is present, `is_present()` will return `True` and `get()` will return the value. | ||
If a value is not present, `is_present()` will return `False` | ||
and `get()` will raise a `ValueError`. | ||
Additional methods provide ways to handle the presence or absence of a contained value. | ||
This class is inspired by Java's `Optional` class. | ||
""" | ||
|
||
def __init__(self, value=None): | ||
""" | ||
Constructs an Optional with the given value. | ||
If the value is None, the Optional is considered empty. | ||
""" | ||
self._value = value | ||
self._is_present = value is not None | ||
|
||
@staticmethod | ||
def of(value): | ||
""" | ||
Returns an Optional with the given non-none value. | ||
Raises a ValueError if the value is None. | ||
""" | ||
if value is None: | ||
raise ValueError("Value cannot be None") | ||
return Optional(value) | ||
|
||
@staticmethod | ||
def empty(): | ||
"""Returns an empty Optional.""" | ||
return Optional() | ||
|
||
def is_present(self): | ||
"""Returns `True` if the Optional contains a non-none value, `False` otherwise.""" | ||
return self._is_present | ||
|
||
def get(self): | ||
"""Returns the value if present, otherwise raises a `ValueError`.""" | ||
if not self._is_present: | ||
raise ValueError("Value is not present") | ||
return self._value | ||
|
||
def or_else(self, default_value): | ||
"""Returns the value if present, otherwise returns the given default value.""" | ||
return self._value if self._is_present else default_value | ||
|
||
def or_else_get(self, supplier): | ||
""" | ||
Returns the value if present, otherwise calls the given supplier function to get a | ||
default value. | ||
""" | ||
return self._value if self._is_present else supplier() | ||
|
||
def map(self, mapper): | ||
""" | ||
Applies the given mapper function to the value if present, returning a new Optional | ||
with the result. | ||
If the Optional is empty, returns an empty Optional. | ||
""" | ||
if not self._is_present: | ||
return Optional() | ||
mapped_value = mapper(self._value) | ||
return Optional(mapped_value) | ||
|
||
def flat_map(self, mapper): | ||
""" | ||
Applies the given mapper function to the value if present, returning the result. | ||
If the Optional is empty, returns an empty Optional. | ||
If the mapper function does not return an Optional, raises a TypeError. | ||
""" | ||
if not self._is_present: | ||
return Optional() | ||
optional_result = mapper(self._value) | ||
if not isinstance(optional_result, Optional): | ||
raise TypeError("Mapper function must return an Optional") | ||
return optional_result | ||
|
||
def filter(self, predicate): | ||
""" | ||
Returns an Optional containing the value if present and the predicate is true, | ||
otherwise an empty Optional. | ||
""" | ||
return self if self._is_present and predicate(self._value) else Optional() | ||
|
||
def if_present(self, consumer): | ||
"""Calls the given consumer function with the value if present, otherwise does nothing.""" | ||
if self._is_present: | ||
consumer(self._value) | ||
|
||
def __str__(self): | ||
"""Returns a string representation of the Optional.""" | ||
return f"Optional({self._value if self._is_present else ''})" | ||
|
||
def __repr__(self): | ||
"""Returns a string representation of the Optional.""" | ||
return self.__str__() | ||
|
||
def __eq__(self, other): | ||
""" | ||
Returns `True` if the other object is an Optional with the same value, | ||
`False` otherwise. | ||
""" | ||
return self._value == other._value if isinstance(other, Optional) else False | ||
|
||
def __hash__(self): | ||
"""Returns the hash of the Optional's value.""" | ||
return hash(self._value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.