Giter VIP home page Giter VIP logo

Comments (10)

hank121314 avatar hank121314 commented on July 16, 2024

You save data with it, but later on, you add a RawRepresentable conformance. The previous persisted version of the struct can no longer be loaded as it's saved using the Codable bridge.

For this case, we could consider enhancing the RawRepresentableCodableBridge.
Since its Value conforms to both Codable and RawRepresentable, we could test which deserialization can be loaded.
If the user switches the protocol from Codable to RawRepresentable, there may be a need for some migration.

from defaults.

sindresorhus avatar sindresorhus commented on July 16, 2024

Since its Value conforms to both Codable and RawRepresentable, we could test which deserialization can be loaded.

A value could potentially be loadable by both. This creates ambiguity and potential data-loss.

If the user switches the protocol from Codable to RawRepresentable, there may be a need for some migration.

Yes, that's a different case and unrelated to this issue.

from defaults.

hank121314 avatar hank121314 commented on July 16, 2024

A value could potentially be loadable by both. This creates ambiguity and potential data-loss.

How about change the deserialize function in RawRepresentableCodableBridge to this?

public func deserialize(_ object: Serializable?) -> Value? {
		// Check whether it can deserialize with `CodableBridge`
		if 
			let jsonString = object as? String,
			let value = try? Value(jsonString: jsonString) 
		{
				return value
		}
		guard let object = object as Value.RawValue else {
			return nil
		}
		return Value(rawValue: object)
}

It will accept serialization values from both CodableBridge and RawRepresentableBridge.

from defaults.

sindresorhus avatar sindresorhus commented on July 16, 2024

To clarify my point. The potential problem is that the raw serialized value could be a string from a RawRepresentable serialization, but when deserialized using Codable it turns into a different value. I don't think we should guess the user's intent. It's better to be explicit about what you want.

In addition, trying to use Codable each time deserialize() is called would add a lot of unnecessary overhead, since Codable is slow.

from defaults.

hank121314 avatar hank121314 commented on July 16, 2024

Get your point.
I think we might need to allow the user to choose the Bridge they want to use for serialization and deserialization.
Here are the few solutions I come up:

  1. Remove all ambiguous conformance in Defaults, and expose the internal bridge publicly to allow users to choose it.
private enum FixtureCodableEnum: String, Hashable, Codable, Defaults.Serializable {
	case tenMinutes = "10 Minutes"
	case halfHour = "30 Minutes"
	case oneHour = "1 Hour"
}

extension FixtureCodableEnum {
	typealias Bridge = Defaults.RawRepresentableCodableBridge<Self>;
}
  1. Check conformance during Defaults.Key.init and issue an Xcode warning advising users to utilize Defaults.Serializable.RawRepresentable instead.
// in `Defaults.Key.init`
if defaultValue is Codable, defaultValue is any RawRepresentable {
	runtimeWarn(false, "Please consider using `Defaults.Serializable.RawRepresentable` for serialization/deserialization stability")
}

from defaults.

sindresorhus avatar sindresorhus commented on July 16, 2024

Why not?

private enum FixtureCodableEnum: String, Hashable, Codable, Defaults.Serializable.RawRepresentable {
	case tenMinutes = "10 Minutes"
	case halfHour = "30 Minutes"
	case oneHour = "1 Hour"
}

from defaults.

hank121314 avatar hank121314 commented on July 16, 2024

Why not?

Yeah, of course we can do this, but we might need to warn user when they are using ambiguous bridge to do the serialization and deserialization. With this user will need to specify the bridge they want to use.

from defaults.

sindresorhus avatar sindresorhus commented on July 16, 2024

I think 2 would be the best choice.

from defaults.

hank121314 avatar hank121314 commented on July 16, 2024

I think 2 would be the best choice.

Got it! Many thanks!
With option 2, I think there might be a need to also having a Defaults.Serializable.Codable?

from defaults.

sindresorhus avatar sindresorhus commented on July 16, 2024

With option 2, I think there might be a need to also having a Defaults.Serializable.Codable?

Yes. And Defaults.Serializable.NSSecureCoding.

from defaults.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.