diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4c92918..404b558 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,4 +4,4 @@ # See: https://help.github.com/articles/about-codeowners/ # These owners will be the default owners for everything in the repo. -* @gimantha @MaryamZi @hasithaa +* @gimantha @MaryamZi @hasithaa @SasinduDilshara diff --git a/ballerina/tests/from_json_string_test.bal b/ballerina/tests/from_json_string_test.bal index bb4902e..50c4f3d 100644 --- a/ballerina/tests/from_json_string_test.bal +++ b/ballerina/tests/from_json_string_test.bal @@ -60,6 +60,43 @@ isolated function testSimpleJsonStringToRecord() returns Error? { test:assertEquals(recC.get("b"), 1); } +@test:Config +isolated function testSimpleJsonStringToRecord2() returns Error? { + string user = string `{"id": 4012}`; + ReadOnlyUserRecord r = check parseString(user); + test:assertEquals(r, {id: 4012}); +} + +@test:Config +isolated function testSimpleJsonStringToRecord3() returns Error? { + string user = string `{"id": 4012, "name": {"firstname": "John", "lastname": "Doe"}, "age": 27}`; + ReadOnlyUserRecord2 r = check parseString(user); + test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}}); +} + +@test:Config +isolated function testSimpleJsonStringToRecord4() returns Error? { + string user = string `{"id": 4012, "name": {"firstname": "John", "lastname": "Doe"}, "age": 27}`; + UserRecord3 r = check parseString(user); + test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}}); +} + +@test:Config +isolated function testSimpleJsonStringToRecord5() returns Error? { + string user = string `{"id": 4012, "name": {"firstname": "John", "lastname": "Doe"}, "age": 27}`; + ReadOnlyUserRecord2 r = check parseString(user); + test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}}); +} + +@test:Config +isolated function testSimpleJsonStringToRecord6() returns Error? { + string user = string `{"ids": [4012, 4013], "names": [{"firstname": "John", "lastname": "Doe"}, + {"firstname": "Jane", "lastname": "Doe"}], "age": 27}`; + ReadOnlyUsersRecord3 r = check parseString(user); + test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"}, + {firstname: "Jane", lastname: "Doe"}]}); +} + @test:Config isolated function testSimpleJsonStringToRecordWithProjection() returns Error? { string str = string `{"a": "hello", "b": 1}`; diff --git a/ballerina/tests/from_json_test.bal b/ballerina/tests/from_json_test.bal index c2fc4cc..131e83a 100644 --- a/ballerina/tests/from_json_test.bal +++ b/ballerina/tests/from_json_test.bal @@ -67,6 +67,69 @@ isolated function testSimpleJsonToRecord() returns Error? { test:assertEquals(recC.get("b"), 1); } +type ReadOnlyUserRecord readonly & record {| + int id; +|}; + +@test:Config +isolated function testSimpleJsonToRecord2() returns Error? { + json user = {id: 4012}; + ReadOnlyUserRecord r = check parseAsType(user); + test:assertEquals(r, {id: 4012}); +} + +public type ReadonlyUserId readonly & int; + +public type ReadonlyUserName readonly & record { + string firstname; + string lastname; +}; + +type ReadOnlyUserRecord2 readonly & record {| + ReadonlyUserId id; + ReadonlyUserName name; + int age; +|}; + +@test:Config +isolated function testSimpleJsonToRecord3() returns Error? { + json user = {id: 4012, name: {firstname: "John", lastname: "Doe"}, age: 27}; + ReadOnlyUserRecord2 r = check parseAsType(user); + test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}}); +} + +type UserRecord3 ReadOnlyUserRecord2; + +@test:Config +isolated function testSimpleJsonToRecord4() returns Error? { + json user = {id: 4012, name: {firstname: "John", lastname: "Doe"}, age: 27}; + UserRecord3 r = check parseAsType(user); + test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}}); +} + +@test:Config +isolated function testSimpleJsonToRecord5() returns Error? { + ReadonlyUserName username = {firstname: "John", lastname: "Doe"}; + record{string firstname; string lastname;} nameRec = username; + json user = {id: 4012, name: nameRec.toJson(), age: 27}; + ReadOnlyUserRecord2 r = check parseAsType(user); + test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}}); +} + +type ReadOnlyUsersRecord3 readonly & record {| + ReadonlyUserId[] ids; + ReadonlyUserName[] names; +|}; + +@test:Config +isolated function testSimpleJsonToRecord6() returns Error? { + json user = {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"}, + {firstname: "Jane", lastname: "Doe"}], age: 27}; + ReadOnlyUsersRecord3 r = check parseAsType(user); + test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"}, + {firstname: "Jane", lastname: "Doe"}]}); +} + @test:Config isolated function testSimpleJsonToRecordWithProjection() returns Error? { json j = {"a": "hello", "b": 1}; diff --git a/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonParser.java b/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonParser.java index ad911a2..a3c4de7 100644 --- a/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonParser.java +++ b/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonParser.java @@ -249,7 +249,7 @@ public Object execute(Reader reader, BMap options, Type type) t } case TypeTags.INTERSECTION_TAG -> { Type effectiveType = ((IntersectionType) type).getEffectiveType(); - if (!SymbolFlags.isFlagOn(SymbolFlags.READONLY, effectiveType.getFlags())) { + if (!effectiveType.isReadOnly()) { throw DiagnosticLog.error(DiagnosticErrorCode.UNSUPPORTED_TYPE, type); } diff --git a/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonTraverse.java b/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonTraverse.java index fc4e704..3008574 100644 --- a/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonTraverse.java +++ b/native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonTraverse.java @@ -158,7 +158,7 @@ private Object traverseJson(Object json, Type type) { } case TypeTags.INTERSECTION_TAG -> { Type effectiveType = ((IntersectionType) referredType).getEffectiveType(); - if (!SymbolFlags.isFlagOn(SymbolFlags.READONLY, effectiveType.getFlags())) { + if (!effectiveType.isReadOnly()) { throw DiagnosticLog.error(DiagnosticErrorCode.UNSUPPORTED_TYPE, type); } for (Type constituentType : ((IntersectionType) referredType).getConstituentTypes()) {