1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2019, Brandon Nielsen
4# All rights reserved.
5#
6# This software may be modified and distributed under the terms
7# of the BSD license.  See the LICENSE file for details.
8
9from aniso8601.exceptions import ISOFormatError
10
11class BaseTimeBuilder(object):
12    @classmethod
13    def build_date(cls, YYYY=None, MM=None, DD=None, Www=None, D=None,
14                   DDD=None):
15        raise NotImplementedError
16
17    @classmethod
18    def build_time(cls, hh=None, mm=None, ss=None, tz=None):
19        raise NotImplementedError
20
21    @classmethod
22    def build_datetime(cls, date, time):
23        raise NotImplementedError
24
25    @classmethod
26    def build_duration(cls, PnY=None, PnM=None, PnW=None, PnD=None, TnH=None,
27                       TnM=None, TnS=None):
28        raise NotImplementedError
29
30    @classmethod
31    def build_interval(cls, start=None, end=None, duration=None):
32        #start, end, and duration are all tuples
33        raise NotImplementedError
34
35    @classmethod
36    def build_repeating_interval(cls, R=None, Rnn=None, interval=None):
37        #interval is a tuple
38        raise NotImplementedError
39
40    @classmethod
41    def build_timezone(cls, negative=None, Z=None, hh=None, mm=None, name=''):
42        raise NotImplementedError
43
44    @staticmethod
45    def cast(value, castfunction, caughtexceptions=(ValueError,),
46             thrownexception=ISOFormatError, thrownmessage=None):
47
48        try:
49            result = castfunction(value)
50        except caughtexceptions:
51            raise thrownexception(thrownmessage)
52
53        return result
54
55    @classmethod
56    def _build_object(cls, parsetuple):
57        #Given a TupleBuilder tuple, build the correct object
58        if parsetuple[-1] == 'date':
59            return cls.build_date(YYYY=parsetuple[0], MM=parsetuple[1],
60                                  DD=parsetuple[2], Www=parsetuple[3],
61                                  D=parsetuple[4], DDD=parsetuple[5])
62        elif parsetuple[-1] == 'time':
63            return cls.build_time(hh=parsetuple[0], mm=parsetuple[1],
64                                  ss=parsetuple[2], tz=parsetuple[3])
65        elif parsetuple[-1] == 'datetime':
66            return cls.build_datetime(parsetuple[0], parsetuple[1])
67        elif parsetuple[-1] == 'duration':
68            return cls.build_duration(PnY=parsetuple[0], PnM=parsetuple[1],
69                                      PnW=parsetuple[2], PnD=parsetuple[3],
70                                      TnH=parsetuple[4], TnM=parsetuple[5],
71                                      TnS=parsetuple[6])
72        elif parsetuple[-1] == 'interval':
73            return cls.build_interval(start=parsetuple[0], end=parsetuple[1],
74                                      duration=parsetuple[2])
75        elif parsetuple[-1] == 'repeatinginterval':
76            return cls.build_repeating_interval(R=parsetuple[0],
77                                                Rnn=parsetuple[1],
78                                                interval=parsetuple[2])
79
80        return cls.build_timezone(negative=parsetuple[0], Z=parsetuple[1],
81                                  hh=parsetuple[2], mm=parsetuple[3],
82                                  name=parsetuple[4])
83
84class TupleBuilder(BaseTimeBuilder):
85    #Builder used to return the arguments as a tuple, cleans up some parse methods
86    @classmethod
87    def build_date(cls, YYYY=None, MM=None, DD=None, Www=None, D=None,
88                   DDD=None):
89
90        return (YYYY, MM, DD, Www, D, DDD, 'date')
91
92    @classmethod
93    def build_time(cls, hh=None, mm=None, ss=None, tz=None):
94        return (hh, mm, ss, tz, 'time')
95
96    @classmethod
97    def build_datetime(cls, date, time):
98        return (date, time, 'datetime')
99
100    @classmethod
101    def build_duration(cls, PnY=None, PnM=None, PnW=None, PnD=None, TnH=None,
102                       TnM=None, TnS=None):
103
104        return (PnY, PnM, PnW, PnD, TnH, TnM, TnS, 'duration')
105
106    @classmethod
107    def build_interval(cls, start=None, end=None, duration=None):
108        return (start, end, duration, 'interval')
109
110    @classmethod
111    def build_repeating_interval(cls, R=None, Rnn=None, interval=None):
112        return (R, Rnn, interval, 'repeatinginterval')
113
114    @classmethod
115    def build_timezone(cls, negative=None, Z=None, hh=None, mm=None, name=''):
116        return (negative, Z, hh, mm, name, 'timezone')
117