diff --git a/item/date.go b/item/date.go index 23edd69..5e48174 100644 --- a/item/date.go +++ b/item/date.go @@ -66,7 +66,6 @@ func (d *Date) UnmarshalJSON(data []byte) error { } func NewDate(year, month, day int) Date { - if year == 0 || month == 0 || month > 12 || day == 0 { return Date{} } diff --git a/item/event.go b/item/event.go index 5f35ed0..b919a59 100644 --- a/item/event.go +++ b/item/event.go @@ -1,111 +1,110 @@ package item import ( - "encoding/json" - "fmt" "time" ) type EventBody struct { Title string `json:"title"` - Start time.Time `json:"start"` + Date Date `json:"date"` + Time Time `json:"time"` Duration time.Duration `json:"duration"` } -func (e EventBody) MarshalJSON() ([]byte, error) { - type Alias EventBody - return json.Marshal(&struct { - Start string `json:"start"` - Duration string `json:"duration"` - *Alias - }{ - Start: e.Start.UTC().Format(time.RFC3339), - Duration: e.Duration.String(), - Alias: (*Alias)(&e), - }) -} +// func (e EventBody) MarshalJSON() ([]byte, error) { +// type Alias EventBody +// return json.Marshal(&struct { +// Start string `json:"start"` +// Duration string `json:"duration"` +// *Alias +// }{ +// Start: e.Start.UTC().Format(time.RFC3339), +// Duration: e.Duration.String(), +// Alias: (*Alias)(&e), +// }) +// } -func (e *EventBody) UnmarshalJSON(data []byte) error { - type Alias EventBody - aux := &struct { - Start string `json:"start"` - Duration string `json:"duration"` - *Alias - }{ - Alias: (*Alias)(e), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } +// func (e *EventBody) UnmarshalJSON(data []byte) error { +// type Alias EventBody +// aux := &struct { +// Start string `json:"start"` +// Duration string `json:"duration"` +// *Alias +// }{ +// Alias: (*Alias)(e), +// } +// if err := json.Unmarshal(data, &aux); err != nil { +// return err +// } - var err error - if e.Start, err = time.Parse(time.RFC3339, aux.Start); err != nil { - return err - } +// var err error +// if e.Start, err = time.Parse(time.RFC3339, aux.Start); err != nil { +// return err +// } - if e.Duration, err = time.ParseDuration(aux.Duration); err != nil { - return err - } +// if e.Duration, err = time.ParseDuration(aux.Duration); err != nil { +// return err +// } - return nil -} +// return nil +// } -type Event struct { - ID string `json:"id"` - Recurrer Recurrer `json:"recurrer"` - RecurNext time.Time `json:"recurNext"` - EventBody -} +// type Event struct { +// ID string `json:"id"` +// Recurrer Recurrer `json:"recurrer"` +// RecurNext time.Time `json:"recurNext"` +// EventBody +// } -func NewEvent(i Item) (Event, error) { - if i.Kind != KindEvent { - return Event{}, fmt.Errorf("item is not an event") - } +// func NewEvent(i Item) (Event, error) { +// if i.Kind != KindEvent { +// return Event{}, fmt.Errorf("item is not an event") +// } - var e Event - if err := json.Unmarshal([]byte(i.Body), &e); err != nil { - return Event{}, fmt.Errorf("could not unmarshal item body: %v", err) - } +// var e Event +// if err := json.Unmarshal([]byte(i.Body), &e); err != nil { +// return Event{}, fmt.Errorf("could not unmarshal item body: %v", err) +// } - e.ID = i.ID - e.Recurrer = i.Recurrer - e.RecurNext = i.RecurNext +// e.ID = i.ID +// e.Recurrer = i.Recurrer +// e.RecurNext = i.RecurNext - return e, nil -} +// return e, nil +// } -func (e Event) Item() (Item, error) { - body, err := json.Marshal(EventBody{ - Title: e.Title, - Start: e.Start, - Duration: e.Duration, - }) - if err != nil { - return Item{}, fmt.Errorf("could not marshal event to json") - } +// func (e Event) Item() (Item, error) { +// body, err := json.Marshal(EventBody{ +// Title: e.Title, +// Start: e.Start, +// Duration: e.Duration, +// }) +// if err != nil { +// return Item{}, fmt.Errorf("could not marshal event to json") +// } - return Item{ - ID: e.ID, - Kind: KindEvent, - Recurrer: e.Recurrer, - RecurNext: e.RecurNext, - Body: string(body), - }, nil -} +// return Item{ +// ID: e.ID, +// Kind: KindEvent, +// Recurrer: e.Recurrer, +// RecurNext: e.RecurNext, +// Body: string(body), +// }, nil +// } -func (e Event) Valid() bool { - if e.Title == "" { - return false - } - if e.Start.IsZero() || e.Start.Year() < 2024 { - return false - } - if e.Duration.Seconds() < 1 { - return false - } - // if e.Recurrer != nil && !e.Recurrer.Valid() { - // return false - // } +// func (e Event) Valid() bool { +// if e.Title == "" { +// return false +// } +// if e.Start.IsZero() || e.Start.Year() < 2024 { +// return false +// } +// if e.Duration.Seconds() < 1 { +// return false +// } +// // if e.Recurrer != nil && !e.Recurrer.Valid() { +// // return false +// // } - return true -} +// return true +// } diff --git a/item/time.go b/item/time.go new file mode 100644 index 0000000..af7ae0c --- /dev/null +++ b/item/time.go @@ -0,0 +1,70 @@ +package item + +import ( + "encoding/json" + "time" +) + +const ( + TimeFormat = "15:04" +) + +type Time struct { + t time.Time +} + +func (t Time) MarshalJSON() ([]byte, error) { + return json.Marshal(t.String()) +} + +func (t *Time) UnmarshalJSON(data []byte) error { + timeString := "" + if err := json.Unmarshal(data, &timeString); err != nil { + return err + } + nt := NewTimeFromString(timeString) + t.t = nt.Time() + + return nil +} + +func NewTime(hour, minute int) Time { + return Time{ + t: time.Date(0, 0, 0, hour, minute, 0, 0, time.UTC), + } +} + +func NewTimeFromString(timeStr string) Time { + tm, err := time.Parse(TimeFormat, timeStr) + if err != nil { + return Time{t: time.Time{}} + } + + return Time{t: tm} +} + +func (t *Time) String() string { + return t.t.Format(TimeFormat) +} + +func (t *Time) Time() time.Time { + return t.t +} + +func (t *Time) IsZero() bool { + return t.t.IsZero() +} + +func (t *Time) Hour() int { + return t.t.Hour() +} + +func (t *Time) Minute() int { + return t.t.Minute() +} + +func (t *Time) Add(d time.Duration) Time { + return Time{ + t: t.t.Add(d), + } +} diff --git a/item/time_test.go b/item/time_test.go new file mode 100644 index 0000000..3811cca --- /dev/null +++ b/item/time_test.go @@ -0,0 +1,67 @@ +package item_test + +import ( + "encoding/json" + "fmt" + "testing" + + "go-mod.ewintr.nl/planner/item" +) + +func TestTime(t *testing.T) { + t.Parallel() + + h, m := 11, 18 + tm := item.NewTime(h, m) + expStr := "11:18" + if expStr != tm.String() { + t.Errorf("exp %v, got %v", expStr, tm.String()) + } + actJSON, err := json.Marshal(tm) + if err != nil { + t.Errorf("exp nil, got %v", err) + } + expJSON := fmt.Sprintf("%q", expStr) + if expJSON != string(actJSON) { + t.Errorf("exp %v, got %v", expJSON, string(actJSON)) + } + var actTM item.Time + if err := json.Unmarshal(actJSON, &actTM); err != nil { + t.Errorf("exp nil, got %v", err) + } + if expStr != actTM.String() { + t.Errorf("ecp %v, got %v", expStr, actTM.String()) + } +} + +func TestTimeFromString(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + name string + str string + exp string + }{ + { + name: "empty", + exp: "00:00", + }, + { + name: "invalid", + str: "invalid", + exp: "00:00", + }, + { + name: "valid", + str: "11:42", + exp: "11:42", + }, + } { + t.Run(tc.name, func(t *testing.T) { + act := item.NewTimeFromString(tc.str) + if tc.exp != act.String() { + t.Errorf("exp %v, got %v", tc.exp, act.String()) + } + }) + } +} diff --git a/plan/storage/storage.go b/plan/storage/storage.go index 9dc2794..080ba89 100644 --- a/plan/storage/storage.go +++ b/plan/storage/storage.go @@ -2,70 +2,66 @@ package storage import ( "errors" - "sort" - "time" - - "go-mod.ewintr.nl/planner/item" ) var ( ErrNotFound = errors.New("not found") ) -type LocalID interface { - FindAll() (map[string]int, error) - FindOrNext(id string) (int, error) - Next() (int, error) - Store(id string, localID int) error - Delete(id string) error -} +// type LocalID interface { +// FindAll() (map[string]int, error) +// FindOrNext(id string) (int, error) +// Next() (int, error) +// Store(id string, localID int) error +// Delete(id string) error +// } -type Sync interface { - FindAll() ([]item.Item, error) - Store(i item.Item) error - DeleteAll() error - LastUpdate() (time.Time, error) -} +// type Sync interface { +// FindAll() ([]item.Item, error) +// Store(i item.Item) error +// DeleteAll() error +// LastUpdate() (time.Time, error) +// } -type Event interface { - Store(event item.Event) error - Find(id string) (item.Event, error) - FindAll() ([]item.Event, error) - Delete(id string) error -} +// type Event interface { +// Store(event item.Event) error +// Find(id string) (item.Event, error) +// FindAll() ([]item.Event, error) +// Delete(id string) error +// } -func NextLocalID(used []int) int { - if len(used) == 0 { - return 1 - } +// func NextLocalID(used []int) int { +// if len(used) == 0 { +// return 1 +// } - sort.Ints(used) - usedMax := 1 - for _, u := range used { - if u > usedMax { - usedMax = u - } - } +// sort.Ints(used) +// usedMax := 1 +// for _, u := range used { +// if u > usedMax { +// usedMax = u +// } +// } - var limit int - for limit = 1; limit <= len(used) || limit < usedMax; limit *= 10 { - } +// var limit int +// for limit = 1; limit <= len(used) || limit < usedMax; limit *= 10 { +// } - newId := used[len(used)-1] + 1 - if newId < limit { - return newId - } +// newId := used[len(used)-1] + 1 +// if newId < limit { +// return newId +// } - usedMap := map[int]bool{} - for _, u := range used { - usedMap[u] = true - } +// usedMap := map[int]bool{} +// for _, u := range used { +// usedMap[u] = true +// } - for i := 1; i < limit; i++ { - if _, ok := usedMap[i]; !ok { - return i - } - } +// for i := 1; i < limit; i++ { +// if _, ok := usedMap[i]; !ok { +// return i +// } +// } - return limit -} +// return limit +// } diff --git a/sync/service/memory.go b/sync/service/memory.go index ca92346..84f3a88 100644 --- a/sync/service/memory.go +++ b/sync/service/memory.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "slices" "sync" "time" @@ -48,32 +47,33 @@ func (m *Memory) Updated(kinds []item.Kind, timestamp time.Time) ([]item.Item, e } func (m *Memory) RecursBefore(date time.Time) ([]item.Item, error) { - res := make([]item.Item, 0) - for _, i := range m.items { - if i.Recurrer == nil { - continue - } - if i.RecurNext.Before(date) { - res = append(res, i) - } - } - return res, nil + // res := make([]item.Item, 0) + // for _, i := range m.items { + // if i.Recurrer == nil { + // continue + // } + // if i.RecurNext.Before(date) { + // res = append(res, i) + // } + // } + // return res, nil + return nil, nil } func (m *Memory) RecursNext(id string, date time.Time, ts time.Time) error { - i, ok := m.items[id] - if !ok { - return ErrNotFound - } - if i.Recurrer == nil { - return ErrNotARecurrer - } - if !i.Recurrer.On(date) { - return fmt.Errorf("item does not recur on %v", date) - } - i.RecurNext = date - i.Updated = ts - m.items[id] = i + // i, ok := m.items[id] + // if !ok { + // return ErrNotFound + // } + // if i.Recurrer == nil { + // return ErrNotARecurrer + // } + // if !i.Recurrer.On(date) { + // return fmt.Errorf("item does not recur on %v", date) + // } + // i.RecurNext = date + // i.Updated = ts + // m.items[id] = i return nil }