package command import ( "fmt" "strconv" "strings" "time" "go-mod.ewintr.nl/planner/plan/storage" ) type Update struct { localIDRepo storage.LocalID eventRepo storage.Event syncRepo storage.Sync argSet *ArgSet localID int } func NewUpdate(localIDRepo storage.LocalID, eventRepo storage.Event, syncRepo storage.Sync) Command { return &Update{ localIDRepo: localIDRepo, eventRepo: eventRepo, syncRepo: syncRepo, argSet: &ArgSet{ Flags: map[string]Flag{ FlagTitle: &FlagString{}, FlagOn: &FlagDate{}, FlagAt: &FlagTime{}, FlagFor: &FlagDuration{}, }, }, } } func (update *Update) Parse(main []string, flags map[string]string) error { if len(main) < 2 || main[0] != "update" { return ErrWrongCommand } localID, err := strconv.Atoi(main[1]) if err != nil { return fmt.Errorf("not a local id: %v", main[1]) } update.localID = localID as := update.argSet if len(main) > 1 { as.Main = strings.Join(main[1:], " ") } for k := range as.Flags { v, ok := flags[k] if !ok { continue } if err := as.Set(k, v); err != nil { return fmt.Errorf("could not set %s: %v", k, err) } } return nil } func (update *Update) Do() error { as := update.argSet var id string idMap, err := update.localIDRepo.FindAll() if err != nil { return fmt.Errorf("could not get local ids: %v", err) } for eid, lid := range idMap { if update.localID == lid { id = eid } } if id == "" { return fmt.Errorf("could not find local id") } e, err := update.eventRepo.Find(id) if err != nil { return fmt.Errorf("could not find event") } if as.Main != "" { e.Title = as.Main } if onStr != "" || atStr != "" { oldStart := e.Start dateStr := oldStart.Format("2006-01-02") if onStr != "" { dateStr = onStr } timeStr := oldStart.Format("15:04") if atStr != "" { timeStr = atStr } newStart, err := time.Parse("2006-01-02 15:04", fmt.Sprintf("%s %s", dateStr, timeStr)) if err != nil { return fmt.Errorf("could not parse new start: %v", err) } e.Start = newStart } if frStr != "" { // no check on at, can set a duration with at 00:00, making it not a whole day fr, err := time.ParseDuration(frStr) if err != nil { return fmt.Errorf("%w: could not parse duration: %s", ErrInvalidArg, err) } e.Duration = fr } if err := eventRepo.Store(e); err != nil { return fmt.Errorf("could not store event: %v", err) } it, err := e.Item() if err != nil { return fmt.Errorf("could not convert event to sync item: %v", err) } if err := syncRepo.Store(it); err != nil { return fmt.Errorf("could not store sync item: %v", err) } return nil }