func (p *Profile) Update(update *ProfileUpdate) (*Profile, error) {
	if update.DTag == DoNotModify {
		update.DTag = p.DTag
	}
	if update.Nickname == DoNotModify {
		update.Nickname = p.Nickname
	}
	if update.Bio == DoNotModify {
		update.Bio = p.Bio
	}
	if update.Pictures.Profile == DoNotModify {
		update.Pictures.Profile = p.Pictures.Profile
	}
	if update.Pictures.Cover == DoNotModify {
		update.Pictures.Cover = p.Pictures.Cover
	}
	newProfile, err := NewProfile(
		update.DTag,
		update.Nickname,
		update.Bio,
		update.Pictures,
		p.CreationDate,
		p.GetAccount(),
	)
	if err != nil {
		return nil, err
	}
	return newProfile, nil
}
Update updates the fields of a given profile without validating it.
Before storing the updated profile, a validation with Validate() should
be performed.
package types
import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
	"github.com/ghodss/yaml"
	"github.com/gogo/protobuf/proto"
)
var (
	_ authtypes.AccountI = (*Profile)(nil)
)
func NewProfile(
	dTag string, nickname, bio string, pictures Pictures, creationDate time.Time,
	account authtypes.AccountI,
) (*Profile, error) {
	protoAccount, ok := account.(proto.Message)
	if !ok {
		return nil, fmt.Errorf("the given account cannot be serialized using Protobuf")
	}
	myAccountAny, err := codectypes.NewAnyWithValue(protoAccount)
	if err != nil {
		return nil, err
	}
	return &Profile{
		DTag:         dTag,
		Nickname:     nickname,
		Bio:          bio,
		Pictures:     pictures,
		CreationDate: creationDate,
		Account:      myAccountAny,
	}, nil
}
func NewProfileFromAccount(dTag string, account authtypes.AccountI, creationTime time.Time) (*Profile, error) {
	return NewProfile(
		dTag,
		"",
		"",
		NewPictures("", ""),
		creationTime,
		account,
	)
}
func (p *Profile) GetAccount() authtypes.AccountI {
	return p.Account.GetCachedValue().(authtypes.AccountI)
}
func (p *Profile) setAccount(account authtypes.AccountI) error {
	accAny, err := codectypes.NewAnyWithValue(account)
	if err != nil {
		return err
	}
	p.Account = accAny
	return nil
}
func (p *Profile) GetAddress() sdk.AccAddress {
	return p.GetAccount().GetAddress()
}
func (p *Profile) SetAddress(addr sdk.AccAddress) error {
	acc := p.GetAccount()
	err := acc.SetAddress(addr)
	if err != nil {
		return err
	}
	return p.setAccount(acc)
}
func (p *Profile) GetPubKey() cryptotypes.PubKey {
	return p.GetAccount().GetPubKey()
}
func (p *Profile) SetPubKey(pubKey cryptotypes.PubKey) error {
	acc := p.GetAccount()
	err := acc.SetPubKey(pubKey)
	if err != nil {
		return err
	}
	return p.setAccount(acc)
}
func (p *Profile) GetAccountNumber() uint64 {
	return p.GetAccount().GetAccountNumber()
}
func (p *Profile) SetAccountNumber(accountNumber uint64) error {
	acc := p.GetAccount()
	err := acc.SetAccountNumber(accountNumber)
	if err != nil {
		return err
	}
	return p.setAccount(acc)
}
func (p *Profile) GetSequence() uint64 {
	return p.GetAccount().GetSequence()
}
func (p *Profile) SetSequence(sequence uint64) error {
	acc := p.GetAccount()
	err := acc.SetSequence(sequence)
	if err != nil {
		return err
	}
	return p.setAccount(acc)
}
func (p *Profile) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
	if p.Account != nil {
		var account authtypes.AccountI
		err := unpacker.UnpackAny(p.Account, &account)
		if err != nil {
			return err
		}
	}
	return nil
}
func (p *Profile) Validate() error {
	if strings.TrimSpace(p.DTag) == "" || p.DTag == DoNotModify {
		return fmt.Errorf("invalid profile DTag: %s", p.DTag)
	}
	if p.Nickname == DoNotModify {
		return fmt.Errorf("invalid profile nickname: %s", p.Nickname)
	}
	if p.Bio == DoNotModify {
		return fmt.Errorf("invalid profile bio: %s", p.Bio)
	}
	if p.Pictures.Profile == DoNotModify {
		return fmt.Errorf("invalid profile picture: %s", p.Pictures.Profile)
	}
	if p.Pictures.Cover == DoNotModify {
		return fmt.Errorf("invalid profile cover: %s", p.Pictures.Cover)
	}
	if len(p.GetAddress()) == 0 {
		return fmt.Errorf("invalid address: %s", p.GetAddress().String())
	}
	return p.Pictures.Validate()
}
type profilePretty struct {
	Address       sdk.AccAddress `json:"address" yaml:"address"`
	PubKey        string         `json:"public_key" yaml:"public_key"`
	AccountNumber uint64         `json:"account_number" yaml:"account_number"`
	Sequence      uint64         `json:"sequence" yaml:"sequence"`
	DTag          string         `json:"dtag" yaml:"dtag"`
	Nickname      string         `json:"nickname" yaml:"nickname"`
	Bio           string         `json:"bio" yaml:"bio"`
	Pictures      Pictures       `json:"pictures" yaml:"pictures"`
	CreationDate  time.Time      `json:"creation_date" yaml:"creation_date"`
}
func (p *Profile) String() string {
	out, _ := p.MarshalYAML()
	return out.(string)
}
func (p *Profile) MarshalYAML() (interface{}, error) {
	bs, err := yaml.Marshal(profilePretty{
		Address:       p.GetAddress(),
		PubKey:        p.GetPubKey().String(),
		AccountNumber: p.GetAccountNumber(),
		Sequence:      p.GetSequence(),
		DTag:          p.DTag,
		Nickname:      p.Nickname,
		Bio:           p.Bio,
		Pictures:      p.Pictures,
		CreationDate:  p.CreationDate,
	})
	if err != nil {
		return nil, err
	}
	return string(bs), nil
}
func (p Profile) MarshalJSON() ([]byte, error) {
	var pubKey = ""
	if p.GetPubKey() != nil {
		pubKey = p.GetPubKey().String()
	}
	return json.Marshal(profilePretty{
		Address:       p.GetAddress(),
		PubKey:        pubKey,
		AccountNumber: p.GetAccountNumber(),
		Sequence:      p.GetSequence(),
		DTag:          p.DTag,
		Nickname:      p.Nickname,
		Bio:           p.Bio,
		Pictures:      p.Pictures,
		CreationDate:  p.CreationDate,
	})
}
type ProfileUpdate struct {
	DTag     string
	Nickname string
	Bio      string
	Pictures Pictures
}
func NewProfileUpdate(dTag, nickname, bio string, pictures Pictures) *ProfileUpdate {
	return &ProfileUpdate{
		DTag:     dTag,
		Nickname: nickname,
		Bio:      bio,
		Pictures: pictures,
	}
}