status-go/multiaccounts/settings/sync_protobuf_factories.go

517 lines
16 KiB
Go

package settings
import (
"bytes"
"encoding/json"
"reflect"
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/sqlite"
)
var (
ErrTypeAssertionFailed = errors.New("type assertion of interface value failed")
)
func buildRawSyncSettingMessage(msg *protobuf.SyncSetting, chatID string) (*common.RawMessage, error) {
encodedMessage, err := proto.Marshal(msg)
if err != nil {
return nil, err
}
return &common.RawMessage{
LocalChatID: chatID,
Payload: encodedMessage,
MessageType: protobuf.ApplicationMetadataMessage_SYNC_SETTING,
ResendAutomatically: true,
}, nil
}
// Currency
func buildRawCurrencySyncMessage(v string, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_CURRENCY,
Value: &protobuf.SyncSetting_ValueString{ValueString: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func currencyProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertString(value)
if err != nil {
return nil, nil, err
}
return buildRawCurrencySyncMessage(v, clock, chatID)
}
func currencyProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawCurrencySyncMessage(s.Currency, clock, chatID)
}
// GifFavorites
func buildRawGifFavoritesSyncMessage(v []byte, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_GIF_FAVOURITES,
Value: &protobuf.SyncSetting_ValueBytes{ValueBytes: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func gifFavouritesProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertBytes(value)
if err != nil {
return nil, nil, err
}
return buildRawGifFavoritesSyncMessage(v, clock, chatID)
}
func gifFavouritesProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
gf := extractJSONRawMessage(s.GifFavorites)
return buildRawGifFavoritesSyncMessage(gf, clock, chatID)
}
// GifRecents
func buildRawGifRecentsSyncMessage(v []byte, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_GIF_RECENTS,
Value: &protobuf.SyncSetting_ValueBytes{ValueBytes: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func gifRecentsProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertBytes(value)
if err != nil {
return nil, nil, err
}
return buildRawGifRecentsSyncMessage(v, clock, chatID)
}
func gifRecentsProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
gr := extractJSONRawMessage(s.GifRecents)
return buildRawGifRecentsSyncMessage(gr, clock, chatID)
}
// MessagesFromContactsOnly
func buildRawMessagesFromContactsOnlySyncMessage(v bool, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_MESSAGES_FROM_CONTACTS_ONLY,
Value: &protobuf.SyncSetting_ValueBool{ValueBool: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func messagesFromContactsOnlyProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertBool(value)
if err != nil {
return nil, nil, err
}
return buildRawMessagesFromContactsOnlySyncMessage(v, clock, chatID)
}
func messagesFromContactsOnlyProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawMessagesFromContactsOnlySyncMessage(s.MessagesFromContactsOnly, clock, chatID)
}
// PreferredName
func buildRawPreferredNameSyncMessage(v string, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_PREFERRED_NAME,
Value: &protobuf.SyncSetting_ValueString{ValueString: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func preferredNameProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertString(value)
if err != nil {
return nil, nil, err
}
return buildRawPreferredNameSyncMessage(v, clock, chatID)
}
func preferredNameProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
var pn string
if s.PreferredName != nil {
pn = *s.PreferredName
}
return buildRawPreferredNameSyncMessage(pn, clock, chatID)
}
// PreviewPrivacy
func buildRawPreviewPrivacySyncMessage(v bool, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_PREVIEW_PRIVACY,
Value: &protobuf.SyncSetting_ValueBool{ValueBool: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func previewPrivacyProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertBool(value)
if err != nil {
return nil, nil, err
}
return buildRawPreviewPrivacySyncMessage(v, clock, chatID)
}
func previewPrivacyProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawPreviewPrivacySyncMessage(s.PreviewPrivacy, clock, chatID)
}
// ProfilePicturesShowTo
func buildRawProfilePicturesShowToSyncMessage(v int64, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_PROFILE_PICTURES_SHOW_TO,
Value: &protobuf.SyncSetting_ValueInt64{ValueInt64: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func profilePicturesShowToProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := parseNumberToInt64(value)
if err != nil {
return nil, nil, err
}
return buildRawProfilePicturesShowToSyncMessage(v, clock, chatID)
}
func profilePicturesShowToProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawProfilePicturesShowToSyncMessage(int64(s.ProfilePicturesShowTo), clock, chatID)
}
// ProfilePicturesVisibility
func buildRawProfilePicturesVisibilitySyncMessage(v int64, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_PROFILE_PICTURES_VISIBILITY,
Value: &protobuf.SyncSetting_ValueInt64{ValueInt64: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func profilePicturesVisibilityProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := parseNumberToInt64(value)
if err != nil {
return nil, nil, err
}
return buildRawProfilePicturesVisibilitySyncMessage(v, clock, chatID)
}
func profilePicturesVisibilityProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawProfilePicturesVisibilitySyncMessage(int64(s.ProfilePicturesVisibility), clock, chatID)
}
// SendStatusUpdates
func buildRawSendStatusUpdatesSyncMessage(v bool, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_SEND_STATUS_UPDATES,
Value: &protobuf.SyncSetting_ValueBool{ValueBool: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func sendStatusUpdatesProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertBool(value)
if err != nil {
return nil, nil, err
}
return buildRawSendStatusUpdatesSyncMessage(v, clock, chatID)
}
func sendStatusUpdatesProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawSendStatusUpdatesSyncMessage(s.SendStatusUpdates, clock, chatID)
}
// StickerPacksInstalled
func buildRawStickerPacksInstalledSyncMessage(v []byte, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_STICKERS_PACKS_INSTALLED,
Value: &protobuf.SyncSetting_ValueBytes{ValueBytes: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func stickersPacksInstalledProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := parseJSONBlobData(value)
if err != nil {
return nil, nil, err
}
return buildRawStickerPacksInstalledSyncMessage(v, clock, chatID)
}
func stickersPacksInstalledProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
spi := extractJSONRawMessage(s.StickerPacksInstalled)
return buildRawStickerPacksInstalledSyncMessage(spi, clock, chatID)
}
// StickerPacksPending
func buildRawStickerPacksPendingSyncMessage(v []byte, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_STICKERS_PACKS_PENDING,
Value: &protobuf.SyncSetting_ValueBytes{ValueBytes: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func stickersPacksPendingProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := parseJSONBlobData(value)
if err != nil {
return nil, nil, err
}
return buildRawStickerPacksPendingSyncMessage(v, clock, chatID)
}
func stickersPacksPendingProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
spp := extractJSONRawMessage(s.StickerPacksPending)
return buildRawStickerPacksPendingSyncMessage(spp, clock, chatID)
}
// StickersRecentStickers
func buildRawStickersRecentStickersSyncMessage(v []byte, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_STICKERS_RECENT_STICKERS,
Value: &protobuf.SyncSetting_ValueBytes{ValueBytes: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func stickersRecentStickersProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := parseJSONBlobData(value)
if err != nil {
return nil, nil, err
}
return buildRawStickersRecentStickersSyncMessage(v, clock, chatID)
}
func stickersRecentStickersProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
srs := extractJSONRawMessage(s.StickersRecentStickers)
return buildRawStickersRecentStickersSyncMessage(srs, clock, chatID)
}
func assertBytes(value interface{}) ([]byte, error) {
v, ok := value.([]byte)
if !ok {
return nil, errors.Wrapf(ErrTypeAssertionFailed, "expected '[]byte', received %T", value)
}
return v, nil
}
func assertBool(value interface{}) (bool, error) {
v, ok := value.(bool)
if !ok {
return false, errors.Wrapf(ErrTypeAssertionFailed, "expected 'bool', received %T", value)
}
return v, nil
}
func assertString(value interface{}) (string, error) {
rv := reflect.ValueOf(value)
if rv.Kind() == reflect.Ptr {
value = *value.(*string)
}
v, ok := value.(string)
if !ok {
return "", errors.Wrapf(ErrTypeAssertionFailed, "expected 'string', received %T", value)
}
return v, nil
}
func parseJSONBlobData(value interface{}) ([]byte, error) {
switch v := value.(type) {
case []byte:
return v, nil
case *sqlite.JSONBlob:
return extractJSONBlob(v)
default:
return nil, errors.Wrapf(ErrTypeAssertionFailed, "expected []byte or *sqlite.JSONBlob, received %T", value)
}
}
func parseNumberToInt64(value interface{}) (int64, error) {
switch v := value.(type) {
case float32:
return int64(v), nil
case float64:
return int64(v), nil
case int:
return int64(v), nil
case int8:
return int64(v), nil
case int16:
return int64(v), nil
case int32:
return int64(v), nil
case int64:
return v, nil
case uint:
return int64(v), nil
case uint8:
return int64(v), nil
case uint16:
return int64(v), nil
case uint32:
return int64(v), nil
case uint64:
return int64(v), nil
case ProfilePicturesShowToType:
return int64(v), nil
case ProfilePicturesVisibilityType:
return int64(v), nil
default:
return 0, errors.Wrapf(ErrTypeAssertionFailed, "expected a numeric type, received %T", value)
}
}
func extractJSONBlob(jb *sqlite.JSONBlob) ([]byte, error) {
value, err := jb.Value()
if err != nil {
return nil, err
}
if value == nil {
return nil, nil
}
return value.([]byte), nil
}
func extractJSONRawMessage(jrm *json.RawMessage) []byte {
if jrm == nil {
return nil
}
out, _ := jrm.MarshalJSON() // Don't need to parse error because it is always nil
if len(out) == 0 || bytes.Equal(out, []byte("null")) {
return nil
}
return out
}
// DisplayName
func buildRawDisplayNameSyncMessage(v string, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_DISPLAY_NAME,
Value: &protobuf.SyncSetting_ValueString{ValueString: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func displayNameProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertString(value)
if err != nil {
return nil, nil, err
}
return buildRawDisplayNameSyncMessage(v, clock, chatID)
}
func displayNameProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawDisplayNameSyncMessage(s.DisplayName, clock, chatID)
}
// Bio
func buildRawBioSyncMessage(v string, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_BIO,
Value: &protobuf.SyncSetting_ValueString{ValueString: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func bioProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertString(value)
if err != nil {
return nil, nil, err
}
return buildRawBioSyncMessage(v, clock, chatID)
}
func bioProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawBioSyncMessage(s.Bio, clock, chatID)
}
// MnemonicRemoved
func buildRawMnemonicRemovedSyncMessage(v bool, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
pb := &protobuf.SyncSetting{
Type: protobuf.SyncSetting_MNEMONIC_REMOVED,
Value: &protobuf.SyncSetting_ValueBool{ValueBool: v},
Clock: clock,
}
rm, err := buildRawSyncSettingMessage(pb, chatID)
return rm, pb, err
}
func mnemonicRemovedProtobufFactory(value interface{}, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
v, err := assertBool(value)
if err != nil {
return nil, nil, err
}
return buildRawMnemonicRemovedSyncMessage(v, clock, chatID)
}
func mnemonicRemovedProtobufFactoryStruct(s Settings, clock uint64, chatID string) (*common.RawMessage, *protobuf.SyncSetting, error) {
return buildRawMnemonicRemovedSyncMessage(s.MnemonicRemoved, clock, chatID)
}