-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrust_enum.py
More file actions
65 lines (48 loc) · 1.8 KB
/
rust_enum.py
File metadata and controls
65 lines (48 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""Rust-style enumerations."""
from collections.abc import Generator
from dataclasses import make_dataclass
from typing import Any, TypeVar, Generic, Callable
def enum(cls):
"""Create enumeration from class."""
for field_name in dir(cls):
if not isinstance((value := getattr(cls, field_name)), Case): continue
setattr(cls, field_name, make_dataclass(field_name, list(value.dict.items()), bases=(cls, )))
return cls
class Case:
"""Class-placeholder for generation of enumeration members."""
def __init__(self, **attributes):
self.dict = attributes
# to disable warnings
def __call__(self, *args, **kwargs):
pass
class UnwrappingError(Exception): pass
T = TypeVar("T")
@enum
class Option(Generic[T]):
Some = Case(value=T)
Nothing = Case()
def unwrap(self) -> T:
match self:
case Option.Some(value): return value
case _: raise UnwrappingError
D = TypeVar("D")
def unwrap_or(self, default_value: D = None) -> T | D:
match self:
case Option.Some(value): return value
case _: return default_value
R = TypeVar("R")
def map(self, mapping_function: Callable[[T], R]) -> "Option[R]":
match self:
case Option.Some(value): return Option.Some(mapping_function(value))
case _: return self
def and_then(self, mapping_function: Callable[[T], R]) -> "Option.Nothing | R":
match self:
case Option.Some(value): return mapping_function(value)
case _: return self
def some(self):
match self:
case Option.Some(_): return True
case _: return False
@classmethod
def next(cls, generator: Generator) -> "Option[Any]":
return next((cls.Some(e) for e in generator), cls.Nothing())