package ldmodel import ( "github.com/launchdarkly/go-jsonstream/v3/jreader" "github.com/launchdarkly/go-jsonstream/v3/jwriter" ) // DataModelSerialization is an abstraction of an encoding for SDK data model objects. // // The ldmodel package defines a standard JSON schema for FeatureFlag and Segment. Currently, this // is the only encoding that is used, so the only implementation of DataModelSerialization is the // one provided by NewDataModelSerialization(), but the interface allows for the possibility that // other encodings will be defined in the future. // // There are also other ways to convert these types to and from the JSON encoding: // // 1. FeatureFlag and Segment define MarshalJSON and UnmarshalJSON methods so that they wil be // correctly encoded or decoded if you call Go's standard json.Marshal or json.Unmarshal. // // 2. There are equivalent methods for encoding and decoding via the go-jsonstream API // (https://pkg.go.dev/github.com/launchdarkly/go-jsonstream/v3). These are used internally by the // SDK to avoid inefficiencies in json.Marshal and json.Unmarshal. // // 3. If the build tag "launchdarkly_easyjson" is set, FeatureFlag and Segment will also define // MarshalEasyJSON and UnmarshalEasyJSON methods for interoperability with the easyjson library. // For details, see the go-jsonstream documentation. // // There is no separately defined encoding for lower-level data model types such as FlagRule, since // there is no guarantee that those will always be represented as individual JSON objects in future // versions of the schema. If you want to create a JSON representation of those data structures you // must define your own type and copy values into it. type DataModelSerialization interface { // MarshalFeatureFlag converts a FeatureFlag into its serialized encoding. MarshalFeatureFlag(item FeatureFlag) ([]byte, error) // MarshalSegment converts a Segment into its serialized encoding. MarshalSegment(item Segment) ([]byte, error) // UnmarshalFeatureFlag attempts to convert a FeatureFlag from its serialized encoding. UnmarshalFeatureFlag(data []byte) (FeatureFlag, error) // UnmarshalFeatureFlag attempts to convert a FeatureFlag from its serialized encoding. UnmarshalSegment(data []byte) (Segment, error) } // MarshalFeatureFlagToJSONWriter attempts to convert a FeatureFlag to JSON using the jsonstream API. // For details, see: https://github.com/launchdarkly/go-jsonstream/v3 func MarshalFeatureFlagToJSONWriter(item FeatureFlag, writer *jwriter.Writer) { marshalFeatureFlagToWriter(item, writer) } // MarshalSegmentToJSONWriter attempts to convert a Segment to JSON using the jsonstream API. // For details, see: https://github.com/launchdarkly/go-jsonstream/v3 func MarshalSegmentToJSONWriter(item Segment, writer *jwriter.Writer) { marshalSegmentToWriter(item, writer) } // UnmarshalFeatureFlagFromJSONReader attempts to convert a FeatureFlag from JSON using the jsonstream // API. For details, see: https://github.com/launchdarkly/go-jsonstream/v3 func UnmarshalFeatureFlagFromJSONReader(reader *jreader.Reader) FeatureFlag { return unmarshalFeatureFlagFromReader(reader) } // UnmarshalSegmentFromJSONReader attempts to convert a Segment from JSON using the jsonstream API. // For details, see: https://github.com/launchdarkly/go-jsonstream/v3 func UnmarshalSegmentFromJSONReader(reader *jreader.Reader) Segment { return unmarshalSegmentFromReader(reader) } type jsonDataModelSerialization struct{} // NewJSONDataModelSerialization provides the default JSON encoding for SDK data model objects. // // Always use this rather than relying on json.Marshal() and json.Unmarshal(). The data model // structs are guaranteed to serialize and deserialize correctly with json.Marshal() and // json.Unmarshal(), but JSONDataModelSerialization may be enhanced in the future to use a // more efficient mechanism. func NewJSONDataModelSerialization() DataModelSerialization { return jsonDataModelSerialization{} } func (s jsonDataModelSerialization) MarshalFeatureFlag(item FeatureFlag) ([]byte, error) { return marshalFeatureFlag(item) } func (s jsonDataModelSerialization) MarshalSegment(item Segment) ([]byte, error) { return marshalSegment(item) } func (s jsonDataModelSerialization) UnmarshalFeatureFlag(data []byte) (FeatureFlag, error) { return unmarshalFeatureFlagFromBytes(data) } func (s jsonDataModelSerialization) UnmarshalSegment(data []byte) (Segment, error) { return unmarshalSegmentFromBytes(data) } // MarshalJSON overrides the default json.Marshal behavior to provide the same marshalling behavior that is // used by NewJSONDataModelSerialization(). func (f FeatureFlag) MarshalJSON() ([]byte, error) { return marshalFeatureFlag(f) } // MarshalJSON overrides the default json.Marshal behavior to provide the same marshalling behavior that is // used by NewJSONDataModelSerialization(). func (s Segment) MarshalJSON() ([]byte, error) { return marshalSegment(s) } // UnmarshalJSON overrides the default json.Unmarshal behavior to provide the same unmarshalling behavior that // is used by NewJSONDataModelSerialization(). func (f *FeatureFlag) UnmarshalJSON(data []byte) error { result, err := unmarshalFeatureFlagFromBytes(data) if err == nil { *f = result } return err } // UnmarshalJSON overrides the default json.Unmarshal behavior to provide the same unmarshalling behavior that // is used by NewJSONDataModelSerialization(). func (s *Segment) UnmarshalJSON(data []byte) error { result, err := unmarshalSegmentFromBytes(data) if err == nil { *s = result } return err }