Coverage for sources/mimeogram/parts.py: 100%

44 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-22 03:00 +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''' Mimeogram parts. ''' 

22 

23 

24from __future__ import annotations 

25 

26from . import __ 

27from . import fsprotect as _fsprotect 

28 

29 

30class LineSeparators( __.enum.Enum ): 

31 ''' Line separators for various platforms. ''' 

32 

33 CR = '\r' # Classic MacOS 

34 CRLF = '\r\n' # DOS/Windows 

35 LF = '\n' # Unix/Linux 

36 

37 @classmethod 

38 def detect_bytes( # pylint: disable=inconsistent-return-statements 

39 selfclass, content: bytes, limit = 1024 

40 ) -> LineSeparators | None: 

41 ''' Detects newline characters in bytes array. ''' 

42 # TODO: Pyright bug? `Self` not recognized as type for enum members 

43 sample = content[ : limit ] 

44 found_cr = False 

45 for byte in sample: 

46 match byte: 

47 case 0xd: 

48 if found_cr: return selfclass.CR 

49 found_cr = True 

50 case 0xa: # linefeed 

51 if found_cr: return selfclass.CRLF 

52 return selfclass.LF 

53 case _: 

54 if found_cr: return selfclass.CR 

55 return 

56 

57 @classmethod 

58 def normalize_universal( selfclass, content: str ) -> str: 

59 ''' Normalizes all varieties of newline characters in text. ''' 

60 return content.replace( '\r\n', '\r' ).replace( '\r', '\n' ) 

61 

62 def nativize( self, content: str ) -> str: 

63 ''' Nativizes specific variety newline characters in text. ''' 

64 if LineSeparators.LF is self: return content 

65 return content.replace( '\n', self.value ) 

66 

67 def normalize( self, content: str ) -> str: 

68 ''' Normalizes specific variety newline characters in text. ''' 

69 if LineSeparators.LF is self: return content 

70 return content.replace( self.value, '\n' ) 

71 

72 

73class Resolutions( __.enum.Enum ): 

74 ''' Available resolutions for each part. ''' 

75 

76 Apply = 'apply' 

77 Ignore = 'ignore' 

78 

79 

80class Part( 

81 metaclass = __.ImmutableStandardDataclass, 

82 decorators = ( __.standard_dataclass, ), 

83): 

84 ''' Part of mimeogram. ''' 

85 location: str # TODO? 'Url' class 

86 mimetype: str 

87 charset: str 

88 linesep: LineSeparators 

89 content: str 

90 

91 # TODO? 'format' method 

92 # TODO? 'parse' method 

93 

94 

95class Target( 

96 metaclass = __.ImmutableStandardDataclass, 

97 decorators = ( __.standard_dataclass, ), 

98): 

99 ''' Target information for mimeogram part. ''' 

100 part: Part 

101 destination: __.Path 

102 protection: _fsprotect.Status