Coverage for sources/mimeogram/__/generics.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-03 00:13 +0000

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

4#============================================================================# 

5# # 

6# Licensed under the Apache License, Version 2.0 (the "License"); # 

7# you may not use this file except in compliance with the License. # 

8# You may obtain a copy of the License at # 

9# # 

10# http://www.apache.org/licenses/LICENSE-2.0 # 

11# # 

12# Unless required by applicable law or agreed to in writing, software # 

13# distributed under the License is distributed on an "AS IS" BASIS, # 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

15# See the License for the specific language governing permissions and # 

16# limitations under the License. # 

17# # 

18#============================================================================# 

19 

20 

21''' Generic types. ''' 

22# TODO: Independent package. 

23 

24 

25from __future__ import annotations 

26 

27from . import imports as __ 

28 

29 

30T = __.typx.TypeVar( 'T' ) # generic 

31U = __.typx.TypeVar( 'U' ) # generic 

32E = __.typx.TypeVar( 'E', bound = Exception ) # error 

33 

34 

35class Result( __.ImmutableObject, __.typx.Generic[ T, E ] ): 

36 ''' Either a value or an error. ''' 

37 # TODO: Protocol class. 

38 

39 def is_error( self ) -> bool: 

40 ''' Returns ``True`` if error result. Else ``False``. ''' 

41 return isinstance( self, Error ) 

42 

43 def is_value( self ) -> bool: 

44 ''' Returns ``True`` if value result. Else ``False``. ''' 

45 return isinstance( self, Value ) 

46 

47 @__.abc.abstractmethod 

48 def extract( self ) -> T: 

49 ''' Extracts value from result. Else, raises error from result. 

50 

51 Similar to Result.unwrap in Rust. 

52 ''' 

53 raise NotImplementedError 

54 

55 @__.abc.abstractmethod 

56 def transform( 

57 self, function: __.typx.Callable[ [ T ], U ] 

58 ) -> __.typx.Self | Result[ U, E ]: 

59 ''' Transforms value in value result. Ignores error result. 

60 

61 Similar to Result.map in Rust. 

62 ''' 

63 raise NotImplementedError 

64 

65 

66class Value( Result[ T, E ] ): 

67 ''' Result of successful computation. ''' 

68 

69 __match_args__ = ( 'value', ) 

70 __slots__ = ( 'value', ) 

71 

72 value: T 

73 

74 def __init__( self, value: T ): self.value = value 

75 

76 def extract( self ) -> T: return self.value 

77 

78 def transform( 

79 self, function: __.typx.Callable[ [ T ], U ] 

80 ) -> Result[ U, E ]: return Value( function( self.value ) ) 

81 

82 

83class Error( Result[ T, E ] ): 

84 ''' Result of failed computation. ''' 

85 

86 __match_args__ = ( 'error', ) 

87 __slots__ = ( 'error', ) 

88 

89 error: E 

90 

91 def __init__( self, error: E ): self.error = error 

92 

93 def extract( self ) -> __.typx.Never: raise self.error 

94 

95 def transform( 

96 self, function: __.typx.Callable[ [ T ], U ] 

97 ) -> __.typx.Self: return self 

98 

99 

100GenericResult: __.typx.TypeAlias = Result[ __.typx.Any, Exception ]