/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/protocol/gregor1/factory.go
308 строк
8 KB
Marcel O'Neil
Migrate to Go Modules (#24023)
22 ноя 2021, 20:07
Не верифицирован
22 ноя 2021, 20:07
a66861b
Код
Авторство
О чём код?
package gregor1 import ( "bytes" "errors" "sort" "time" "github.com/keybase/client/go/gregor" "github.com/keybase/go-codec/codec" ) type ObjFactory struct{} func (o ObjFactory) MakeUID(b []byte) (gregor.UID, error) { return UID(b), nil } func (o ObjFactory) MakeMsgID(b []byte) (gregor.MsgID, error) { return MsgID(b), nil } func (o ObjFactory) MakeDeviceID(b []byte) (gregor.DeviceID, error) { return DeviceID(b), nil } func (o ObjFactory) MakeBody(b []byte) (gregor.Body, error) { return Body(b), nil } func (o ObjFactory) MakeSystem(s string) (gregor.System, error) { return System(s), nil } func (o ObjFactory) MakeCategory(s string) (gregor.Category, error) { return Category(s), nil } func castUID(uid gregor.UID) (ret UID, err error) { if uid == nil { return } ret, ok := uid.(UID) if !ok { err = errors.New("bad UID; wrong type") } return } func castDeviceID(d gregor.DeviceID) (ret DeviceID, err error) { if d == nil { return } ret, ok := d.(DeviceID) if !ok { err = errors.New("bad Device ID; wrong type") } return } func castItem(i gregor.Item) (ret ItemAndMetadata, err error) { ret, ok := i.(ItemAndMetadata) if !ok { err = errors.New("bad Item; wrong type") } return } func castInBandMessage(i gregor.InBandMessage) (ret InBandMessage, err error) { ret, ok := i.(InBandMessage) if !ok { err = errors.New("bad InBandMessage; wrong type") } return } func timeToTimeOrOffset(timeIn *time.Time) (too TimeOrOffset) { if timeIn != nil { too.Time_ = ToTime(*timeIn) } return } func (o ObjFactory) makeMetadata(uid gregor.UID, msgid gregor.MsgID, devid gregor.DeviceID, ctime time.Time, i gregor.InBandMsgType) (Metadata, error) { uid2, e := castUID(uid) if e != nil { return Metadata{}, e } devid2, e := castDeviceID(devid) if e != nil { return Metadata{}, e } return Metadata{ Uid_: uid2, MsgID_: MsgID(msgid.Bytes()), Ctime_: ToTime(ctime), DeviceID_: devid2, InBandMsgType_: int(i), }, nil } func (o ObjFactory) makeItem(c gregor.Category, d *time.Time, b gregor.Body) *Item { return &Item{ Dtime_: timeToTimeOrOffset(d), Category_: Category(c.String()), Body_: Body(b.Bytes()), } } func (o ObjFactory) MakeItem(u gregor.UID, msgid gregor.MsgID, deviceid gregor.DeviceID, ctime time.Time, c gregor.Category, dtime *time.Time, body gregor.Body) (gregor.Item, error) { md, err := o.makeMetadata(u, msgid, deviceid, ctime, gregor.InBandMsgTypeUpdate) if err != nil { return nil, err } return ItemAndMetadata{ Md_: &md, Item_: o.makeItem(c, dtime, body), }, nil } func (o ObjFactory) MakeReminder(i gregor.Item, seqno int, t time.Time) (gregor.Reminder, error) { it, ok := i.(ItemAndMetadata) if !ok { return nil, errors.New("item is not gregor1.ItemAndMetadata") } return Reminder{ Item_: it, Seqno_: seqno, RemindTime_: ToTime(t), }, nil } func (o ObjFactory) MakeDismissalByRange(uid gregor.UID, msgid gregor.MsgID, devid gregor.DeviceID, ctime time.Time, c gregor.Category, d time.Time, skipMsgIDs []gregor.MsgID) (gregor.InBandMessage, error) { md, err := o.makeMetadata(uid, msgid, devid, ctime, gregor.InBandMsgTypeUpdate) if err != nil { return nil, err } var skips []MsgID for _, s := range skipMsgIDs { skips = append(skips, MsgID(s.Bytes())) } return InBandMessage{ StateUpdate_: &StateUpdateMessage{ Md_: md, Dismissal_: &Dismissal{ Ranges_: []MsgRange{{ EndTime_: timeToTimeOrOffset(&d), Category_: Category(c.String()), SkipMsgIDs_: skips, }}, }, }, }, nil } func (o ObjFactory) MakeDismissalByIDs(uid gregor.UID, msgid gregor.MsgID, devid gregor.DeviceID, ctime time.Time, ids []gregor.MsgID) (gregor.InBandMessage, error) { md, err := o.makeMetadata(uid, msgid, devid, ctime, gregor.InBandMsgTypeUpdate) if err != nil { return nil, err } ourIds := make([]MsgID, len(ids)) for i, id := range ids { ourIds[i] = MsgID(id.Bytes()) } return InBandMessage{ StateUpdate_: &StateUpdateMessage{ Md_: md, Dismissal_: &Dismissal{ MsgIDs_: ourIds, }, }, }, nil } func (o ObjFactory) MakeStateSyncMessage(uid gregor.UID, msgid gregor.MsgID, devid gregor.DeviceID, ctime time.Time) (gregor.InBandMessage, error) { md, err := o.makeMetadata(uid, msgid, devid, ctime, gregor.InBandMsgTypeUpdate) if err != nil { return nil, err } return InBandMessage{ StateSync_: &StateSyncMessage{ Md_: md, }, }, nil } type itemSlice []ItemAndMetadata func (its itemSlice) Len() int { return len(its) } func (its itemSlice) Swap(i, j int) { its[i], its[j] = its[j], its[i] } // Less returns true if i's ctime is before j's, or if they're equal and // i's MsgID is lexicographically before j's. func (its itemSlice) Less(i, j int) bool { mI, mJ := its[i].Metadata(), its[j].Metadata() if mI != nil && mJ != nil { if mI.CTime().Equal(mJ.CTime()) { if mI.MsgID() != nil && mJ.MsgID() != nil { return bytes.Compare(mI.MsgID().Bytes(), mJ.MsgID().Bytes()) < 0 } else { return mI.MsgID() == nil } } return mI.CTime().Before(mJ.CTime()) } return mI == nil } func (o ObjFactory) MakeState(items []gregor.Item) (gregor.State, error) { ourItems := make(itemSlice, 0, len(items)) for _, item := range items { ourItem, err := castItem(item) if err != nil { return nil, err } ourItems = append(ourItems, ourItem) } sort.Sort(ourItems) return State{Items_: ourItems}, nil } func (o ObjFactory) MakeStateWithLookupTable(items []gregor.Item, table map[string]gregor.Item) (gregor.State, error) { return o.MakeState(items) } func (o ObjFactory) MakeMetadata(uid gregor.UID, msgid gregor.MsgID, devid gregor.DeviceID, ctime time.Time, i gregor.InBandMsgType) (gregor.Metadata, error) { return o.makeMetadata(uid, msgid, devid, ctime, gregor.InBandMsgTypeUpdate) } func (o ObjFactory) MakeInBandMessageFromItem(i gregor.Item) (gregor.InBandMessage, error) { ourItem, err := castItem(i) if err != nil { return nil, err } return InBandMessage{ StateUpdate_: &StateUpdateMessage{ Md_: *ourItem.Md_, Creation_: ourItem.Item_, }, }, nil } func (o ObjFactory) MakeMessageFromInBandMessage(i gregor.InBandMessage) (gregor.Message, error) { ourInBandMessage, err := castInBandMessage(i) if err != nil { return nil, err } return Message{ Ibm_: &ourInBandMessage, }, nil } func (o ObjFactory) UnmarshalState(b []byte) (gregor.State, error) { var state State err := codec.NewDecoderBytes(b, &codec.MsgpackHandle{WriteExt: true}). Decode(&state) if err != nil { return nil, err } return state, nil } func (o ObjFactory) UnmarshalMessage(b []byte) (gregor.Message, error) { var message Message err := codec.NewDecoderBytes(b, &codec.MsgpackHandle{WriteExt: true}).Decode(&message) if err != nil { return nil, err } return message, nil } func (o ObjFactory) MakeTimeOrOffsetFromTime(t time.Time) (gregor.TimeOrOffset, error) { return timeToTimeOrOffset(&t), nil } func (o ObjFactory) MakeTimeOrOffsetFromOffset(d time.Duration) (gregor.TimeOrOffset, error) { return TimeOrOffset{Offset_: DurationMsec(d / time.Millisecond)}, nil } func (o ObjFactory) ExportTimeOrOffset(t gregor.TimeOrOffset) TimeOrOffset { if t.Time() != nil { return TimeOrOffset{ Time_: ToTime(*t.Time()), } } if t.Offset() != nil { return TimeOrOffset{ Offset_: DurationMsec(*t.Offset() / time.Millisecond), } } return TimeOrOffset{} } func (o ObjFactory) ExportTimeOrOffsets(ts []gregor.TimeOrOffset) (res []TimeOrOffset) { for _, t := range ts { res = append(res, o.ExportTimeOrOffset(t)) } return res } func (o ObjFactory) MakeReminderID(u gregor.UID, msgid gregor.MsgID, seqno int) (gregor.ReminderID, error) { return ReminderID{Uid_: u.Bytes(), MsgID_: msgid.Bytes(), Seqno_: seqno}, nil } func (o ObjFactory) MakeReminderSetFromReminders(reminders []gregor.Reminder, moreRemindersReady bool) (gregor.ReminderSet, error) { ret := ReminderSet{MoreRemindersReady_: moreRemindersReady} for _, reminder := range reminders { if r, ok := reminder.(Reminder); ok { ret.Reminders_ = append(ret.Reminders_, r) } else { return nil, errors.New("Can't upcast reminder") } } return ret, nil } func (o ObjFactory) MakeOutOfBandMessage(uid gregor.UID, system gregor.System, body gregor.Body) gregor.Message { return Message{ Oobm_: &OutOfBandMessage{Uid_: uid.Bytes(), System_: System(system.String()), Body_: body.Bytes()}, } } var _ gregor.ObjFactory = ObjFactory{}