Coverage for arbejdstimer/api.py: 100.00%

34 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-04 15:36:40 +00:00

1# -*- coding: utf-8 -*- 

2# pylint: disable=expression-not-assigned,line-too-long 

3"""Working hours (Danish arbejdstimer) or not? API model.""" 

4from __future__ import annotations 

5 

6from datetime import date 

7from enum import Enum 

8from typing import Annotated, List, Optional, no_type_check 

9 

10from pydantic import BaseModel, Field, RootModel, model_validator 

11 

12 

13class Application(Enum): 

14 arbejdstimer = 'arbejdstimer' 

15 

16 

17class Operator(Enum): 

18 and_ = 'and' 

19 or_ = 'or' 

20 xor = 'xor' 

21 

22 

23class Hour(RootModel[Annotated[int, Field(ge=0.0, le=23.0)]]): 

24 pass 

25 

26 

27class WorkingHours( 

28 RootModel[ 

29 Annotated[ 

30 List[Hour], 

31 Field( 

32 description='Inclusive range of 24 hour start and end integer values.', 

33 max_length=2, 

34 min_length=2, 

35 title='Working Hours', 

36 ), 

37 ] 

38 ] 

39): 

40 pass 

41 

42 

43class Dates( 

44 RootModel[ 

45 Annotated[ 

46 List[date], 

47 Field( 

48 description='Two dates are an inclusive range and 1, 3, or more dates represent a set of dates.', 

49 min_length=1, 

50 title='Dates - Range or Set', 

51 ), 

52 ] 

53 ] 

54): 

55 @no_type_check 

56 @model_validator(mode='before') 

57 def is_unique(cls, v): 

58 if v and 1 < len(v) != len(set(v)): 

59 raise ValueError('dates must be unique') 

60 return v 

61 

62 

63class Holiday(BaseModel): 

64 label: Annotated[Optional[str], Field(examples=['public holiday'])] = '' 

65 at: Dates 

66 

67 

68class Holidays( 

69 RootModel[ 

70 Annotated[ 

71 List[Holiday], 

72 Field( 

73 description='Optionally labeled dates of non-working days.', 

74 min_length=0, 

75 title='Holidays', 

76 ), 

77 ] 

78 ] 

79): 

80 pass 

81 

82 

83class Arbejdstimer(BaseModel): 

84 api: Annotated[ 

85 Optional[int], 

86 Field( 

87 description='API version of the application this configuration targets.', 

88 title='API Version', 

89 ), 

90 ] = 1 

91 application: Annotated[ 

92 Optional[Application], 

93 Field( 

94 description='Name of the application this configuration targets.', 

95 title='Application Name', 

96 ), 

97 ] = Application.arbejdstimer 

98 operator: Annotated[ 

99 Operator, 

100 Field( 

101 description='Logic combining the given specific values with the application defaults.', 

102 title='Logic for Combination with Default Values', 

103 ), 

104 ] 

105 holidays: Optional[Holidays] = None 

106 working_hours: Optional[WorkingHours] = None