Skip to content

Fix trait codegen for timestamp member with timestampformat trait#2744

Merged
joewyz merged 1 commit intomainfrom
joewyz/fix-trait-codegen-incorrect-timestamp-members
Aug 18, 2025
Merged

Fix trait codegen for timestamp member with timestampformat trait#2744
joewyz merged 1 commit intomainfrom
joewyz/fix-trait-codegen-incorrect-timestamp-members

Conversation

@joewyz
Copy link
Contributor

@joewyz joewyz commented Aug 15, 2025

Current trait codegen implementation cannot generate correct fromNode() and createNode() for timestamp members because traits carried by the MemberShape are ignored by the generators. This PR fixes this by adding special handling for @timestampFormat trait.
For example, the following model:

@trait
structure StructMemberWithTimestampFormat {
    @timestampFormat("date-time")
    memberDateTime: Timestamp

    @timestampFormat("http-date")
    memberHttpDate: Timestamp

    memberEpochSeconds: MemberEpochSeconds

    memberList: TimeStampList

    memberMap: StringTimeStampMap
}

@timestampFormat("epoch-seconds")
timestamp MemberEpochSeconds

list TimeStampList {
    @timestampFormat("http-date")
    member: Timestamp
}

map StringTimeStampMap {
    key: String
    @timestampFormat("http-date")
    value:Timestamp
}

The generated fromNode() method after fix:

public static StructMemberWithTimestampFormatTrait fromNode(Node node) {
        Builder builder = builder().sourceLocation(node);
        node.expectObjectNode()
            .getMember("memberDateTime", n -> Instant.parse(n.expectStringNode().getValue()), builder::memberDateTime)
            .getMember("memberHttpDate", n -> Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(n.expectStringNode().getValue())), builder::memberHttpDate)
            .getMember("memberEpochSeconds", n -> Instant.ofEpochSecond(n.expectNumberNode().getValue().longValue()), builder::memberEpochSeconds)
            .getArrayMember("memberList", n -> Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(n.expectStringNode().getValue())), builder::memberList)
            .getObjectMember("memberMap", o -> {
                Map<String, Instant> value1 = new LinkedHashMap<>();
                Map<StringNode, Node> members1 = o.expectObjectNode().getMembers();
                for (Entry<StringNode, Node> entry1 : members1.entrySet()) {
                    Instant value2 = Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(entry1.getValue().expectStringNode().getValue()));
                    String key2 = entry1.getKey().expectStringNode().getValue();
                    value1.put(key2, value2);
                }
                builder.memberMap(value1);
            });
        return builder.build();
}

The generated createNode(() method after fix:

@Override
protected Node createNode() {
        return Node.objectNodeBuilder()
            .sourceLocation(getSourceLocation())
            .withOptionalMember("memberDateTime", getMemberDateTime().map(m -> Node.from(m.toString())))
            .withOptionalMember("memberHttpDate", getMemberHttpDate().map(m -> Node.from(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.ofInstant(m, ZoneOffset.UTC)))))
            .withOptionalMember("memberEpochSeconds", getMemberEpochSeconds().map(m -> Node.from(m.getEpochSecond())))
            .withOptionalMember("memberList", getMemberList().map(m -> {
                ArrayNode.Builder builder1 = ArrayNode.builder();
                for (Instant element2 : m) {
                    builder1.withValue(Node.from(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.ofInstant(element2, ZoneOffset.UTC))));
                }
                return builder1.build();
            }))
            .withOptionalMember("memberMap", getMemberMap().map(m -> {
                ObjectNode.Builder builder1 = ObjectNode.builder();
                for (Entry<String, Instant> entry2 : m.entrySet()) {
                    StringNode key2 = Node.from(entry2.getKey());
                    builder1.withMember(key2, Node.from(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.ofInstant(entry2.getValue(), ZoneOffset.UTC))));
                }
                return builder1.build();
            }))
            .build();
}

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@joewyz joewyz requested a review from a team as a code owner August 15, 2025 23:00
@joewyz joewyz requested a review from JordonPhillips August 15, 2025 23:00
@joewyz joewyz merged commit 9f2c66f into main Aug 18, 2025
9 checks passed
@joewyz joewyz deleted the joewyz/fix-trait-codegen-incorrect-timestamp-members branch August 18, 2025 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants