!ފ.S      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR(c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNone&'48=>?HMVX_kf3 safe-json Version profile of a consistent  instance. safe-json,Version of the type checked for consistency. safe-json0All versions in the chain with their type names. safe-json)Profile of the internal consistency of a  instance.N.B.  shows as null instead of a number. safe-json(There is something wrong with versioning safe-jsonProfile of consistent versions  safe-jsonThe  of a + type determines how it can be migrated to.  safe-jsonQThis 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.  safe-jsonA simple numeric version id.  has a S< instance and should be declared using integer literals:  = 2 safe-jsonHThis is an impenetrable container. A security measure used to ensure  and 1 are never used directly. Instead, always use # and ". safe-jsonTThis instance is needed to handle the migration between older and newer versions.Note that, where ( a)3 migrates from the previous version to the type a, ( (  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 s.)  instance  NewType where type  NewType = OldType  OldType = NewType instance  (  OldType) where type  (  OldType) = NewType  NewType =   OldType  safe-json-The type from which will be migrated to type a safe-json?The migration from the previous version to the current type a. OR, in case of a (  a)G, the migration from the future version back to the current type a safe-jsonQA 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. safe-jsonThe 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). safe-jsonThe 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  safe-jsonThis method defines how a value should be serialized without worrying about adding the version. The default implementation uses T$, but can be modified if need be.+This function cannot be used directly. Use " , instead. safe-jsonThis method defines how a value should be parsed without also worrying about writing out the version tag. The default implementation uses U$, but can be modified if need be.+This function cannot be used directly. Use # , instead. safe-jsonGThe name of the type. This is used in error message strings and the  report.+Doesn't have to be defined if your type is V#. The default implementation is $. (cf. %, &, etc.) safe-jsonVersion profile.XShows the current version of the type and all supported versions it can migrate from. safe-jsonUsed when defining  or . safe-json8This 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.  =  is distinctively different from  = 0#, which will add a version tag with the number 0 (zero), whereas  will not add a  tag. safe-jsonSame as , but requires a   parameter.:'encode' $ 'setVersion'' ('version' :: 'Version' Test) val"{\"~v\":0,\"~d\":\"test\"}" safe-json>CAUTION: Only use this function if you know what you're doing. =The version will be set top-level, without inspection of the W!(cf. C) In some rare cases, you might want to interpret a versionless W as a certain type/version. 4 allows you to (unsafely) insert a version field.$If possible, it is advised to use a X instance instead. (One that doesn't also use # in its methods!)This might be needed when data sent to an API endpoint doesn't need to implement SafeJSON standards. E.g. in the case of endpoints for third parties or customers. KUSAGE: {-# LANGUAGE TypeApplications #-} data Test = Test String instance  Test where ... >>> val = Y "test" :: W String "test" >>> Z val ""test"" >>> Z $ 1 @Test val "{"~v":0,"~d":"test"}" >>> parseMaybe # $  @Test val Just (Test "test")  safe-json>CAUTION: Only use this function if you know what you're doing.(cf. )  removes all the  versioning from a JSON W. 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. safe-jsonUsed to define . Base types do not extend any type. safe-jsonUsed to define  . Extends a previous version.  safe-jsonUsed to define . Types that are  i, are extended by a future version and as such can migrate backward from that future version. (cf. !, )! safe-jsonUsed 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.  , )" safe-json#Use this exactly how you would use T 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 W created. If the W resulting from  (by default the same as T ) is an W7, 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 W is not an W5, 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.# safe-json#Use this exactly how you would use U 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 Wi 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.$ safe-json%Type name string representation of a nullary type constructor.% safe-json%Type name string representation of a unary type constructor.& safe-json%Type name string representation of a binary type constructor.' safe-json%Type name string representation of a ternary type constructor.( safe-json%Type name string representation of a 4-ary type constructor.) safe-json%Type name string representation of a 5-ary type constructor.[ safe-jsongEasy way to get a printable failure/success report of the internal consistency of a SafeJSON instance.* safe-json Similar to \, but ed to be used in  definitions+ safe-json Similar to ], but ed to be used in  definitions, safe-json Similar to ^, but ed to be used in  definitions- safe-json Similar to _, but ed to be used in  definitions. safe-json Similar to `, but ed to be used in  definitions/ safe-json Similar to a , but uses #= instead of parseJSON to parse the value in the given field.0 safe-json Similar to b , but uses #C instead of parseJSON to maybe parse the value in the given field.1 safe-json Similar to c , but uses #C instead of parseJSON to maybe parse the value in the given field.2 safe-json Similarly to d , but uses "@ instead of toJSON to convert the value in that key-value pair.e safe-json*This instance explicitly doesn't consider 2, since it is an exception in almost every sense.f safe-json<It is strongly discouraged to use any methods other than g of  'Version'\'s S instance.h safe-json  Nothing shows as nulli safe-jsonJLists 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.Sjkl mno pqrstuv !wxy"#z$%&'(){|}[~*+,-./012(c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNone1  !"#$%&'()*+,-./0121"#*+,-./012   !$%&'() (c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNone63 safe-jsonTry to decode a  to a  value.4 safe-jsonTry to decode a  to a  value.5 safe-jsonTry to decode a  to a 0 value. Produces an error message on failure.6 safe-jsonTry to decode a  to a 0 value. Produces an error message on failure.7 safe-json Encode a  value to a .8 safe-jsonTry to decode a  to a  value.9 safe-jsonTry to decode a  to a  value.: safe-jsonTry to decode a  to a 0 value. Produces an error message on failure.; safe-jsonTry to decode a  to a 0 value. Produces an error message on failure.< safe-jsonSame as 7, but also calls , for convenience.= safe-jsonTry to decode a file to a  value.> safe-jsonTry to decode a file to a  value.? safe-jsonTry to decode a file to a 0 value. Produces an error message on failure.@ safe-jsonTry to decode a file to a 0 value. Produces an error message on failure.A safe-json Encode a  value to a file.dcba`_]^\XWY  !"#$%&'()*+,-./0123456789:;<=>?@A3456789:;<=>?@A(c) 2019 Felix PaulusmaMITfelix.paulusma@gmail.com experimentalNone ,>HVXB safe-json/Constraints for migrating from a future versionC safe-json1Constraints for migrating from a previous versionD safe-json[Useful in test suites. Will fail if anything in the chain of your types is inconsistent.Example usage: testConsistency @MyTypeE safe-json[Useful in test suites. Will fail if anything in the chain of your types is inconsistent.F safe-jsonTests that the following holds:0Just a == parseMaybe safeFromJSON (safeToJSON a)G safe-jsonTests that the following holds for all a:0Just a == parseMaybe safeFromJSON (safeToJSON a)H safe-json'Tests that the following holds for all a:0Just a == parseMaybe safeFromJSON (safeToJSON a)Example usage: testRoundTripProp @MyType sI safe-json1Migration 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)J safe-json Similar to I , 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)K safe-jsonOperator synonymous with IL safe-jsonOperator synonymous with JM safe-jsonzThis test verifies that direct migration, and migration through encoding and decoding to the newer type, is equivalent.N safe-json Similar to MO, but tests the migration from a newer type to the older type, in case of a  (  a) instanceO safe-json}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)P safe-json}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 sQ safe-json Similar to PO, but tests the migration from a newer type to the older type, in case of a  (  a) instance.FJust (unReverse $ migrate a) == parseMaybe safeFromJSON (safeToJSON a)R safe-json Similar to PO, but tests the migration from a newer type to the older type, in case of a  (  a) instance.FJust (unReverse $ migrate a) == parseMaybe safeFromJSON (safeToJSON a)Example usage:8Please also note the reversing of the type applications. /migrateReverseRoundTripProp @OldType @NewType sBCDEFGHIJKLMNOPQRDEIJKLFMNCBHPRGOQK1L1Safe        !"#$ %&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU VWXYZX[\ ]^X_`X[aX_bXcdX[eX[fX[gX[hX[iX[jX[kX[lXYmno Vpqrstuvwxyz{|}~XXXXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXXXXX[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[X[XXX_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_XX     &safe-json-1.1.1-EdISIp58nd8B1S8Qaz2uwGData.SafeJSON.Test Data.SafeJSONData.Aeson.SafeData.SafeJSON.InternalencodetestConsistencydecodePaths_safe_jsonbase Data.ProxyProxyProfileVersionsprofileCurrentVersionprofileSupportedVersionsProfileInvalidProfileKindReverse unReverseVersion ContainedMigrate MigrateFrommigrateSafeJSONversionkindsafeTosafeFromtypeName objectProfilecontain noVersion setVersion' setVersion removeVersion extension extended_baseextended_extension safeToJSON safeFromJSON typeName0 typeName1 typeName2 typeName3 typeName4 typeName5containWithObjectcontainWithArraycontainWithTextcontainWithScientificcontainWithBool.:$.:$?.:$!.=$decode' eitherDecode eitherDecode' decodeStrict decodeStrict'eitherDecodeStricteitherDecodeStrict' encodeStrictdecodeFileStrictdecodeFileStrict'eitherDecodeFileStricteitherDecodeFileStrict' encodeFileTestReverseMigrate TestMigratetestConsistency' testRoundTriptestRoundTripProp'testRoundTripProp testMigrationtestReverseMigration<=?>=?migrateRoundTripmigrateReverseRoundTripmigrateRoundTripProp'migrateRoundTripPropmigrateReverseRoundTripProp'migrateReverseRoundTripPropGHC.NumNum$aeson-1.5.3.0-G7vJEiAQbIFK6WR6HZydosData.Aeson.Types.ToJSONtoJSONData.Aeson.Types.FromJSON parseJSONData.Typeable.InternalTypeableData.Aeson.Types.InternalValueFromJSONString Data.Aeson mkProfile withObject withArraywithTextwithScientificwithBool.:.:?.:!.=$fArbitraryVersion $fNumVersion fromInteger$fShowProfileVersions $fSafeJSON[] Consistency Consistent NotConsistentExtendedExtendsBase unVersion unsafeUnpackinternalConsistencyliftV castVersion versionFielddataVersionField dataFieldconstructParserFromVersionnoVersionPresentshowVshowVscheckConsistencycomputeConsistencyisObviouslyConsistentavailableVersions invalidChainproxyFromVersion kindFromProxyversionFromProxyversionFromKindgetForwardKind withContainedfromGenericVectortoGenericVectorbytestring-0.10.8.2Data.ByteString.Lazy.Internal ByteStringData.ByteString.InternalData.ByteString.LazytoStrictData.Aeson.TypesfoldableData.Aeson.Types.ClassGToJSON GToEncoding toEncoding2toJSON2 toEncoding1toJSON1genericToJSONKeygenericLiftToEncodinggenericToEncodinggenericLiftToJSON genericToJSONGToJSON'ToArgsToJSON toEncoding toJSONListtoEncodingListKeyValue ToJSONKey toJSONKey toJSONKeyListToJSONKeyFunction ToJSONKeyTextToJSONKeyValue GToJSONKeyToJSON1 liftToJSONliftToJSONListliftToEncodingliftToEncodingListToJSON2 liftToJSON2liftToJSONList2liftToEncoding2liftToEncodingList2Data.Aeson.Encoding.Internalpairs fromEncodingEncodingSeries.!=fromJSONwithEmbeddedJSON parseJSON2 parseJSON1genericFromJSONKeygenericLiftParseJSONgenericParseJSONparseIndexedJSON GFromJSONFromArgs parseJSONList FromJSONKey fromJSONKeyfromJSONKeyListFromJSONKeyFunctionFromJSONKeyCoerceFromJSONKeyTextFromJSONKeyTextParserFromJSONKeyValue GFromJSONKey FromJSON1 liftParseJSONliftParseJSONList FromJSON2liftParseJSON2liftParseJSONList2Data.Aeson.Parser.Internaljson'jsoncamelTo2defaultJSONKeyOptionsdefaultTaggedObjectdefaultOptionsobject parseEither parseMaybeJSONPathResultSuccessErrorParserObjectArrayBoolNumberNull DotNetTimefromDotNetTimeOptionsfieldLabelModifierconstructorTagModifierallNullaryToStringTagomitNothingFields sumEncodingunwrapUnaryRecordstagSingleConstructorsrejectUnknownFields SumEncoding TaggedObject UntaggedValueObjectWithSingleField TwoElemArray tagFieldNamecontentsFieldNameJSONKeyOptions keyModifierData.Aeson.Types.GenericZeroOne getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName