-
-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(map): add serialisation for map<string, string> #654
Conversation
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
870203a
to
2cb6ca1
Compare
Signed-off-by: jonathan.casey <[email protected]>
2cb6ca1
to
a6c87fa
Compare
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some questions:
- Don't we want to support Map values other than String?
- Runtime type for maps, support JS object?
@@ -161,18 +161,20 @@ class Serializer { | |||
|
|||
// create a new instance, using the identifier field name as the ID. | |||
let resource; | |||
if (classDeclaration.isTransaction()) { | |||
if (classDeclaration.isTransaction?.()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to loosen this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MapDeclaration doesn't implement isTransaction()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it should? we could move the function to the Declaration
class?
* @return {*} an enum value. | ||
*/ | ||
getMap() { | ||
return new Map([[this.getString(1,10), this.getString(1,10)]]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Values don't have to be strings though... won't this generate invalid maps? I think you want to return a map of N entries, with random string keys (use the same method we use to generate random strings) and then random values, based on the type of the value — again reusing the existing logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but for now we are supporting <String, String> only. In future the method will generate random values of all types supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the grammar for CTO aligned with this?
visitMapDeclaration(mapDeclaration, parameters) { | ||
const obj = parameters.stack.pop(); | ||
|
||
if (!((obj.value instanceof Map))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we not want to accept simple JS objects, indexed as Maps? I think this will force users to create Maps in their code rather than just JS objects.
if (typeof key !== 'string') { | ||
ResourceValidator.reportInvalidMap(parameters.rootResourceIdentifier, mapDeclaration, obj); | ||
} | ||
if (typeof value !== 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only support values that are Strings?
@@ -69,6 +69,7 @@ | |||
"resourcevalidator-undeclaredfield": "Instance \"{resourceId}\" has a property named \"{propertyName}\", which is not declared in \"{fullyQualifiedTypeName}\".", | |||
"resourcevalidator-invalidfieldassignment": "Instance \"{resourceId}\" has a property \"{propertyName}\" with type \"{objectType}\" that is not derived from \"{fieldType}\".", | |||
"resourcevalidator-emptyidentifier": "Instance \"{resourceId}\" has an empty identifier.", | |||
"resourcevalidator-invalidmap": "Model violation in the \"{resourceId}\" instance. Invalid Type for Map Key or Value - expected String type.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Map values have to be Strings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per comment below: The alignment on the first release was <String, String> support only.
|
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: jonathan.casey <[email protected]>
Signed-off-by: Matt Roberts <[email protected]>
@jonathan-casey @mttrbrts @dselman I think it's very unfortunate (and ugly) that the map is pushed down into a "value" property. It seems that the only reason is so that you can put Concerto metadata like $class at the top level of the map without colliding with user keys. However, I'd argue that there is virtually no reason to ever put such metadata there. If you don't intend to allow a map to be extended, e.g. Let's say you were considering map extension. I'd argue it's a bad idea in most cases. There has to be a relation between the keys and values of the base and derived maps. In particular, the derived keys and values could either be a subset or a superset of the base keys and values. In this case, where they're a superset...
This violates the basic expectations of polymorphism, because you can store a B or D2 in M2, thereby violating the requirements of the base map M. This should just never be allowed, from the standpoint of a type system. In the other case, where they're a subset...
First of all, you can already store a D (or D2) as a value in map M via basic polymorphism on B, with no need to extend map M to make that happen. Second, it's backwards from how It's not completely crazy, though. It can make some sense if we analogize to scalars. Let's say there was a way to extend a scalar type:
A derived scalar would be a subset of the base scalar, just as a scalar now is a subset of the base type (e.g. String), and just as, in this case, a derived map is a subset of a base map. The important question, though, is how do you know when to apply the PhoneNumber rules versus the USPhoneNumber rules? Strings have no $class to tell you whether a string is a PhoneNumber or a USPhoneNumber. So how could you do it? It would have to be done based on the declared field type. That is to say, you have extension without polymorphism. And if maps are extended analogously to scalars (i.e. they are a restriction of the base type, not an expansion), and if map polymorphism violates some expectations of polymorphism, then if we allow map extension at all (which I'd argue is less obviously useful than scalar extension with its layered constraints), it should also be extension without polymorphism. And without polymorphism, you need no $class property. Let's look at an example of map extension with polymorphism anyway. Let's say you have
So to summarize:
Overall, the case for needing $class in a map is extremely thin. So can we please move the map data out of the "value" property? This:
looks so much nicer than:
|
@DS-AdamMilazzo thanks for your feedback. I agree with you on the In future it would be most helpful to share your opinion before a sign off. The spec was public and shared for several months prior to implementation. In any case, your feedback is always welcome and appreciated. |
I gladly would have, but these things don't always come to my attention. |
This change adds basic serialisation of a map in the form of <string, string>. Further type variations will follow in subsequent PR.
For more information on the design specification see here
Screenshots or Video
Related Issues
Author Checklist
--signoff
option of git commit.main
fromfork:branchname