ics - sections_alarm.go
1 package ics
2
3 import (
4 "errors"
5 "io"
6
7 "vimagination.zapto.org/parser"
8 )
9
10 type psuedoTokeniser []parser.Phrase
11
12 func (p *psuedoTokeniser) GetPhrase() (parser.Phrase, error) {
13 if len(*p) == 0 {
14 return parser.Phrase{
15 Type: parser.PhraseError,
16 Data: nil,
17 }, io.ErrUnexpectedEOF
18 }
19 ph := (*p)[0]
20 *p = (*p)[1:]
21 return ph, nil
22 }
23
24 // AlarmType is an interface this is fulfilled by AlarmAudio, AlarmDisplay and
25 // AlarmEmail
26 type AlarmType interface {
27 section
28 Type() string
29 }
30
31 // Alarm is the encompassing type for the three alarm types
32 type Alarm struct {
33 AlarmType
34 }
35
36 func (a *Alarm) decode(t tokeniser) error {
37 var pt psuedoTokeniser
38 Loop:
39 for {
40 ph, err := t.GetPhrase()
41 if err != nil {
42 return err
43 }
44 pt = append(pt, ph)
45 switch ph.Data[0].Data {
46 case "BEGIN":
47 return ErrInvalidStructure
48 case "ACTION":
49 if a.AlarmType != nil {
50 return ErrInvalidStructure
51 }
52 switch ph.Data[len(ph.Data)-1].Data {
53 case "AUDIO":
54 a.AlarmType = new(AlarmAudio)
55 case "DISPLAY":
56 a.AlarmType = new(AlarmDisplay)
57 case "EMAIL":
58 a.AlarmType = new(AlarmEmail)
59 case "URI":
60 a.AlarmType = new(AlarmURI)
61 case "NONE":
62 a.AlarmType = new(AlarmNone)
63 }
64 case "END":
65 break Loop
66 }
67 }
68 if a.AlarmType == nil {
69 return ErrMissingAlarmAction
70 }
71 return a.AlarmType.decode(&pt)
72 }
73
74 func (a *Alarm) encode(w writer) {
75 w.WriteString("BEGIN:VALARM\r\n")
76 switch a.AlarmType.(type) {
77 case *AlarmAudio:
78 w.WriteString("ACTION:AUDIO\r\n")
79 case *AlarmDisplay:
80 w.WriteString("ACTION:DISPLAY\r\n")
81 case *AlarmEmail:
82 w.WriteString("ACTION:EMAIL\r\n")
83 case *AlarmURI:
84 w.WriteString("ACTION:URI\r\n")
85 case *AlarmNone:
86 w.WriteString("ACTION:NONE\r\n")
87 }
88 a.AlarmType.encode(w)
89 w.WriteString("END:VALARM\r\n")
90 }
91
92 func (a *Alarm) valid() error {
93 switch a.AlarmType.(type) {
94 case *AlarmAudio, *AlarmDisplay, *AlarmEmail, *AlarmURI, *AlarmNone:
95 return a.AlarmType.valid()
96 }
97 return ErrInvalidAlarm
98 }
99
100 // Type returns the type of the alarm "AUDIO"
101 func (AlarmAudio) Type() string {
102 return "AUDIO"
103 }
104
105 // Type returns the type of the alarm "DISPLAY"
106 func (AlarmDisplay) Type() string {
107 return "DISPLAY"
108 }
109
110 // Type returns the type of the alarm "EMAIL"
111 func (AlarmEmail) Type() string {
112 return "EMAIL"
113 }
114
115 // Type returns the type of the alarm "URI"
116 func (AlarmURI) Type() string {
117 return "URI"
118 }
119
120 // Type returns the type of the alarm "NONE"
121 func (AlarmNone) Type() string {
122 return "NONE"
123 }
124
125 // Errors
126 var (
127 ErrInvalidStructure = errors.New("invalid structure")
128 ErrMissingAlarmAction = errors.New("missing alarm action")
129 ErrInvalidAlarm = errors.New("invalid alarm type")
130 )