tS      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSafeSTUVWXYZ[\]^_`aT[\]^_`aSTUVWXYZ[\]^_`a(c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNone%&269:;DIRT[f3 Version profile of a consistent  instance.,Version of the type checked for consistency.0All versions in the chain with their type names.)Profile of the internal consistency of a  instance.N.B.  shows as null instead of a number.(There is something wrong with versioningProfile of consistent versions The  of a + type determines how it can be migrated to. QThis is a wrapper type used migrating backwards in the chain of compatible types.}This is useful when running updates in production where new-format JSON will be received by old-format expecting programs. A simple numeric version id.  has a b< instance and should be declared using integer literals:  version = 2HThis is an impenetrable container. A security measure used to ensure  and 1 are never used directly. Instead, always use # and ".TThis instance is needed to handle the migration between older and newer versions.Note that, where  (Migrate a)3 migrates from the previous version to the type a, (Migrate (Reverse a))1 migrates from the future version to the type a.Example)Two types that can migrate to each other.(Don't forget to give OldType one of the extended s, and NewType one of the  extension kinds.)  instance  NewType where type  NewType = OldType  OldType = NewType instance  (Reverse OldType) where type  (Reverse OldType) = NewType  NewType = Reverse OldType -The type from which will be migrated to type a?The migration from the previous version to the current type a. OR, in case of a  (Reverse a)G, the migration from the future version back to the current type aQA type that can be converted from and to JSON with versioning baked in, using  to automate migration between versions, reducing headaches when the need arrises to modify JSON formats while old formats can't simply be disregarded.The version of the type.Only used as a key so it must be unique (this is checked at run-time)Version numbering +doesn't have to be sequential or continuous. The default version is 0 (zero).The kind specifies how versions are dealt with. By default, values are tagged with version 0 and don't have any previous versions.The default kind is This method defines how a value should be serialized without worrying about adding the version. The default implementation uses c$, but can be modified if need be.+This function cannot be used directly. Use " , instead.This method defines how a value should be parsed without also worrying about writing out the version tag. The default implementation uses d$, but can be modified if need be.+This function cannot be used directly. Use # , instead.GThe name of the type. This is used in error message strings and the  report.+Doesn't have to be defined if your type is e#. The default implementation is $. (cf. %, &, etc.)Version profile.XShows the current version of the type and all supported versions it can migrate from.Used when defining  or .8This is used for types that don't have a version tag.UThis is used for primitive values that are not tagged with a version number, like Int, Text, [a], etc.But also when implementing Y after the fact, when a format is already in use, but you still want to be able to # from it to a newer type or format.N.B. version = noVersion is distinctively different from  version = 0#, which will add a version tag with the number 0 (zero), whereas  will not add a  version tag.Same as , but requires a   parameter.8'encode' $ 'setVersion'' (version :: 'Version' Test) val"{\"~v\":0,\"~d\":\"test\"}">CAUTION: Only use this function if you know what you're doing. =The version will be set top-level, without inspection of the f!(cf. C) In some rare cases, you might want to interpret a versionless f as a certain type/version. 4 allows you to (unsafely) insert a version field.>CAUTION: Only use this function if you know what you're doing.(cf. )  removes all the  versioning from a JSON f. Even recursively.bThis might be necessary if the resulting JSON is sent to a third party (e.g. customer) and the  versioning should be hidden.Used to define . Base types do not extend any type.Used to define  . Extends a previous version. Used to define . Types that are  i, are extended by a future version and as such can migrate backward from that future version. (cf. !, )!Used to define . Types that are ! are extended by a future version and as such can migrate from that future version, but they also extend a previous version. (cf.  , )"#Use this exactly how you would use c from  Data.Aeson8. Though most use cases will probably use one of the  functions from Data.Aeson.Safe." will add a version tag to the f created. If the f resulting from  (by default the same as c ) is an Object7, an extra field with the version number will be added. hExample value: {"type":"test", "data":true} Resulting object: {"!v": 1, "type":"test", "data":true}If the resulting f is not an Object5, it will be wrapped in one, with a version field: \Example value: "arbitrary string" Resulting object: {"~v": 1, "~d": "arbitrary string"}0This function does not check consistency of the  instances. It is advised to always  for all 'your instances in a production setting.##Use this exactly how you would use d from  Data.Aeson8. Though most use cases will probably use one of the  functions from Data.Aeson.Safe.#1 tries to find the version number in the JSON fi provided, find the appropriate parser and migrate the parsed result back to the requested type using  instances.{If there is no version number (that means this can also happen with completely unrelated JSON messages), and there is a # instance in the chain that has  defined as $, it will try to parse that type.N.B. If the consistency of the  instance in *question is faulty, this will always fail.$%Type name string representation of a nullary type constructor.%%Type name string representation of a unary type constructor.&%Type name string representation of a binary type constructor.'%Type name string representation of a ternary type constructor.(%Type name string representation of a 4-ary type constructor.)%Type name string representation of a 5-ary type constructor.ggEasy way to get a printable failure/success report of the internal consistency of a SafeJSON instance.* Similar to h, but ed to be used in  definitions+ Similar to i, but ed to be used in  definitions, Similar to j, but ed to be used in  definitions- Similar to k, but ed to be used in  definitions. Similar to l, but ed to be used in  definitions/ Similar to m , but uses #= instead of parseJSON to parse the value in the given field.0 Similar to n , but uses #C instead of parseJSON to maybe parse the value in the given field.1 Similar to o , but uses #C instead of parseJSON to maybe parse the value in the given field.2 Similarly to p , but uses "@ instead of toJSON to convert the value in that key-value pair.qJLists and any other "container" are seen as only that: a container for  values. Containers are implemented in such a way that when parsing a collection of all migratable versions, the result will be a list of that type where each element has been migrated as appropriate.rVersion Nothing shows as nulls*This instance explicitly doesn't consider 2, since it is an exception in almost every sense.t<It is strongly discouraged to use any methods other than u of  'Version'\'s b instance.vwx yz{ |}~ !"#$%&'()g*+,-./012qrstSvxw yz{ |}~ !"#$%&'()g*+,-./012vwx yz{  |}~  !"#$%&'()g*+,-./012qrst(c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNone *:DRT3/Constraints for migrating from a future version41Constraints for migrating from a previous version5[Useful in test suites. Will fail if anything in the chain of your types is inconsistent.Example usage: testConsistency @MyType6[Useful in test suites. Will fail if anything in the chain of your types is inconsistent.7Tests that the following holds:0Just a == parseMaybe safeFromJSON (safeToJSON a)8Tests that the following holds for all a:0Just a == parseMaybe safeFromJSON (safeToJSON a)9'Tests that the following holds for all a:0Just a == parseMaybe safeFromJSON (safeToJSON a)Example usage: testRoundTripProp @MyType s:1Migration test. Mostly useful as regression test.eFirst argument is the older type which should turn into the second argument after migrating using .:Just (migrate a) == parseMaybe safeFromJSON (safeToJSON a); Similar to : , but using Migrate (Reverse a).wThe first argument here is the newer type, which will be migrated back to the expected second argument (older type).FJust (unReverse $ migrate a) == parseMaybe safeFromJSON (safeToJSON a)<Operator synonymous with :=Operator synonymous with ;>zThis test verifies that direct migration, and migration through encoding and decoding to the newer type, is equivalent.? Similar to >O, but tests the migration from a newer type to the older type, in case of a Migrate (Reverse a) instance@}This test verifies that direct migration, and migration through encoding and decoding to the newer type, is equivalent for all a.:Just (migrate a) == parseMaybe safeFromJSON (safeToJSON a)A}This test verifies that direct migration, and migration through encoding and decoding to the newer type, is equivalent for all a.:Just (migrate a) == parseMaybe safeFromJSON (safeToJSON a)Example usage: (migrateRoundTripProp @NewType @OldType sBoSimilar to 'migrateRoundTripProp, but tests the migration from a newer type to the older type, in case of a Migrate (Reverse a) instance.FJust (unReverse $ migrate a) == parseMaybe safeFromJSON (safeToJSON a)C Similar to AO, but tests the migration from a newer type to the older type, in case of a Migrate (Reverse a) instance.FJust (unReverse $ migrate a) == parseMaybe safeFromJSON (safeToJSON a)Example usage:8Please also note the reversing of the type applications. /migrateReverseRoundTripProp @OldType @NewType s3456789:;<=>?@ABC3456789:;<=>?@ABC56:;<=7>?439AC8@B3456789:;<=>?@ABC<1=1(c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNone1  !"#$%&'()*+,-./0124"#*+,-./012   !$%&'() (c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNoneDTry to decode a  to a  value.ETry to decode a  to a  value.FTry to decode a  to a 0 value. Produces an error message on failure.GTry to decode a  to a 0 value. Produces an error message on failure.H Encode a  value to a .ITry to decode a  to a  value.JTry to decode a  to a  value.KTry to decode a  to a 0 value. Produces an error message on failure.LTry to decode a  to a 0 value. Produces an error message on failure.MSame as H, but also calls , for convenience.NTry to decode a file to a  value.OTry to decode a file to a  value.PTry to decode a file to a 0 value. Produces an error message on failure.QTry to decode a file to a 0 value. Produces an error message on failure.R Encode a  value to a file.DEFGHIJKLMNOPQRonmlkijh   p   !"#$%&'()*+,-./f0123456789:;<=>?@ABCDEFG  !"#$%&'()*+,-./012DEFGHIJKLMNOPQRDEFGHIJKLMNOPQRDEFGHIJKLMNOPQRH       !"#$ %&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc defghfij klfmnofipfiqfirfisfitfiufivfiwfgxyz{| d}~ffffififififififififififififififififififififififififififififgfgfg fg fg fg fg fgfgfgfgfgfgfgfgfgfgfgfgfgfgfgfgfgfgfg fg!fg"fg#fg$fg%fg&f'(f')f'*f'+f,-f,.f/0f/1fm2fm3fm4fm5fm6fm7fm8fm9fm:fm;fm<fm=fm>fm?fm<fm=fm@fmAfmBfmBfmCfmDfmEfmFfmGfmHfmIfmJfmKfmLfmMfmNfmOfmPfmQfmRSsafe-json-1.0.0-inplaceData.SafeJSON.Test Data.SafeJSONData.Aeson.SafePaths_safe_jsonData.SafeJSON.InternalencodetestConsistencydecodebase Data.ProxyProxyProfileVersionsprofileCurrentVersionprofileSupportedVersionsProfileInvalidProfileKindReverse unReverseVersion ContainedMigrate MigrateFrommigrateSafeJSONversionkindsafeTosafeFromtypeName objectProfilecontain noVersion setVersion' setVersion removeVersion extension extended_baseextended_extension safeToJSON safeFromJSON typeName0 typeName1 typeName2 typeName3 typeName4 typeName5containWithObjectcontainWithArraycontainWithTextcontainWithScientificcontainWithBool.:$.:$?.:$!.=$TestReverseMigrate TestMigratetestConsistency' testRoundTriptestRoundTripProp'testRoundTripProp testMigrationtestReverseMigration<=?>=?migrateRoundTripmigrateReverseRoundTripmigrateRoundTripProp'migrateRoundTripPropmigrateReverseRoundTripProp'migrateReverseRoundTripPropdecode' eitherDecode eitherDecode' decodeStrict decodeStrict'eitherDecodeStricteitherDecodeStrict' encodeStrictdecodeFileStrictdecodeFileStrict'eitherDecodeFileStricteitherDecodeFileStrict' encodeFilecatchIObindirlibdir dynlibdirdatadir libexecdir sysconfdir getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileNameGHC.NumNumNaeson-1.4.1.0-4f7089be379c4e044fcb53872a44f2ec7219f3209344ef543523e64c94011afdData.Aeson.Types.ToJSONtoJSONData.Aeson.Types.FromJSON parseJSONData.Typeable.InternalTypeableData.Aeson.Types.InternalValue mkProfile withObject withArraywithTextwithScientificwithBool.:.:?.:!.= $fSafeJSON[]$fShowProfileVersions$fArbitraryVersion $fNumVersion fromInteger Consistency Consistent NotConsistentBaseExtendsExtended unVersion unsafeUnpackinternalConsistencyliftV castVersion versionFielddataVersionField dataFieldconstructParserFromVersionnoVersionPresentshowVshowVscheckConsistencycomputeConsistencyisObviouslyConsistentavailableVersions invalidChainproxyFromVersion kindFromProxyversionFromProxyversionFromKindgetForwardKind withContainedfromGenericVectortoGenericVector$fSafeJSON(,,,,)$fSafeJSON(,,,)$fSafeJSON(,,) $fSafeJSON(,)$fSafeJSONHashMap$fSafeJSONHashSet $fSafeJSONMap $fSafeJSONSet$fSafeJSONDList$fSafeJSONTree $fSafeJSONSeq$fSafeJSONNonEmpty$fSafeJSONIntMap$fSafeJSONVector$fSafeJSONVector0$fSafeJSONVector1$fSafeJSONVector2$fSafeJSONDual $fSafeJSONMax $fSafeJSONMin$fSafeJSONLast$fSafeJSONFirst$fSafeJSONIdentity$fSafeJSONEither$fSafeJSONMaybe$fSafeJSONConst$fSafeJSONDotNetTime $fSafeJSONDay$fSafeJSONDiffTime$fSafeJSONNominalDiffTime$fSafeJSONUTCTime$fSafeJSONTimeOfDay$fSafeJSONLocalTime$fSafeJSONZonedTime$fSafeJSONCTime $fSafeJSON[]0$fSafeJSONProxy$fSafeJSONFixed$fSafeJSONRatio$fSafeJSONValue$fSafeJSONUUID$fSafeJSONIntSet$fSafeJSONScientific$fSafeJSONVersion$fSafeJSONText$fSafeJSONText0$fSafeJSONWord64$fSafeJSONWord32$fSafeJSONWord16$fSafeJSONWord8$fSafeJSONWord$fSafeJSONInt64$fSafeJSONInt32$fSafeJSONInt16$fSafeJSONInt8$fSafeJSONInteger$fSafeJSONNatural $fSafeJSONInt$fSafeJSONDouble$fSafeJSONFloat$fSafeJSONChar $fSafeJSON()$fSafeJSONOrdering$fSafeJSONBool$fSafeJSONVoid $fShowProfile $fShowVersionbytestring-0.10.8.1Data.ByteString.Lazy.Internal ByteStringData.ByteString.InternalData.ByteString.LazytoStrictData.Aeson.TypesfoldableData.Aeson.Types.ClassGToJSON GToEncoding.!=fromJSONwithEmbeddedJSON parseJSON2 parseJSON1genericLiftParseJSONgenericParseJSON GFromJSON gParseJSONFromArgs NoFromArgs From1ArgsFromJSON parseJSONList FromJSONKey fromJSONKeyfromJSONKeyListFromJSONKeyFunctionFromJSONKeyCoerceFromJSONKeyTextFromJSONKeyTextParserFromJSONKeyValue FromJSON1 liftParseJSONliftParseJSONList FromJSON2liftParseJSON2liftParseJSONList2 toEncoding2toJSON2 toEncoding1toJSON1genericLiftToEncodinggenericToEncodinggenericLiftToJSON genericToJSONToArgsNoToArgsTo1ArgsToJSON toEncoding toJSONListtoEncodingListKeyValue ToJSONKey toJSONKey toJSONKeyListToJSONKeyFunction ToJSONKeyTextToJSONKeyValueToJSON1 liftToJSONliftToJSONListliftToEncodingliftToEncodingListToJSON2 liftToJSON2liftToJSONList2liftToEncoding2liftToEncodingList2Data.Aeson.Encoding.Internalpairs fromEncodingEncodingSeriesData.Aeson.Parser.Internaljson'jsonData.Aeson.Types.GenericZeroOnecamelTo2defaultTaggedObjectdefaultOptionsobject parseEither parseMaybeResultSuccessErrorParserObjectArrayBoolStringNumberNull DotNetTimefromDotNetTimeOptionsfieldLabelModifierconstructorTagModifierallNullaryToStringTagomitNothingFields sumEncodingunwrapUnaryRecordstagSingleConstructors SumEncoding TaggedObject UntaggedValueObjectWithSingleField TwoElemArray tagFieldNamecontentsFieldName