Compare commits
6 Commits
41b61745d2
...
d6b6331def
Author | SHA1 | Date | |
---|---|---|---|
d6b6331def | |||
0a5a08a7ed | |||
6440a58932 | |||
ac30998fa4 | |||
b5aecbad4a | |||
477c23fc7d |
219
src/smithy.zig
219
src/smithy.zig
|
@ -65,6 +65,14 @@ pub const Smithy = struct {
|
||||||
self.allocator.free(v.value);
|
self.allocator.free(v.value);
|
||||||
self.allocator.free(v.traits);
|
self.allocator.free(v.traits);
|
||||||
},
|
},
|
||||||
|
.@"enum" => |v| {
|
||||||
|
for (v.members) |m| self.allocator.free(m.traits);
|
||||||
|
self.allocator.free(v.members);
|
||||||
|
self.allocator.free(v.traits);
|
||||||
|
},
|
||||||
|
.unit => |v| {
|
||||||
|
self.allocator.free(v.traits);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.allocator.free(self.shapes);
|
self.allocator.free(self.shapes);
|
||||||
|
@ -98,20 +106,23 @@ pub const TraitType = enum {
|
||||||
http_payload,
|
http_payload,
|
||||||
json_name,
|
json_name,
|
||||||
xml_name,
|
xml_name,
|
||||||
required,
|
required, // required on the server
|
||||||
|
client_optional, // optional as far as the client is concerned
|
||||||
documentation,
|
documentation,
|
||||||
pattern,
|
pattern,
|
||||||
range,
|
range,
|
||||||
length,
|
length,
|
||||||
box,
|
box,
|
||||||
sparse,
|
sparse,
|
||||||
|
enum_value,
|
||||||
|
aws_query_error,
|
||||||
};
|
};
|
||||||
pub const Trait = union(TraitType) {
|
pub const Trait = union(TraitType) {
|
||||||
aws_api_service: struct {
|
aws_api_service: struct {
|
||||||
sdk_id: []const u8,
|
sdk_id: []const u8,
|
||||||
arn_namespace: []const u8,
|
arn_namespace: ?[]const u8,
|
||||||
cloudformation_name: []const u8,
|
cloudformation_name: ?[]const u8,
|
||||||
cloudtrail_event_source: []const u8,
|
cloudtrail_event_source: ?[]const u8,
|
||||||
endpoint_prefix: []const u8,
|
endpoint_prefix: []const u8,
|
||||||
},
|
},
|
||||||
aws_auth_sigv4: struct {
|
aws_auth_sigv4: struct {
|
||||||
|
@ -131,6 +142,7 @@ pub const Trait = union(TraitType) {
|
||||||
http_query: []const u8,
|
http_query: []const u8,
|
||||||
http_payload: struct {},
|
http_payload: struct {},
|
||||||
required: struct {},
|
required: struct {},
|
||||||
|
client_optional: void,
|
||||||
documentation: []const u8,
|
documentation: []const u8,
|
||||||
pattern: []const u8,
|
pattern: []const u8,
|
||||||
range: struct { // most data is actually integers, but as some are floats, we'll use that here
|
range: struct { // most data is actually integers, but as some are floats, we'll use that here
|
||||||
|
@ -143,6 +155,11 @@ pub const Trait = union(TraitType) {
|
||||||
},
|
},
|
||||||
box: struct {},
|
box: struct {},
|
||||||
sparse: struct {},
|
sparse: struct {},
|
||||||
|
enum_value: []const u8,
|
||||||
|
aws_query_error: struct {
|
||||||
|
http_response_code: i64,
|
||||||
|
code: []const u8,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const ShapeType = enum {
|
const ShapeType = enum {
|
||||||
blob,
|
blob,
|
||||||
|
@ -167,6 +184,8 @@ const ShapeType = enum {
|
||||||
service,
|
service,
|
||||||
operation,
|
operation,
|
||||||
resource,
|
resource,
|
||||||
|
@"enum",
|
||||||
|
unit,
|
||||||
};
|
};
|
||||||
const TraitsOnly = struct {
|
const TraitsOnly = struct {
|
||||||
traits: []Trait,
|
traits: []Trait,
|
||||||
|
@ -225,6 +244,11 @@ const Shape = union(ShapeType) {
|
||||||
traits: []Trait,
|
traits: []Trait,
|
||||||
},
|
},
|
||||||
resource: TraitsOnly,
|
resource: TraitsOnly,
|
||||||
|
@"enum": struct {
|
||||||
|
members: []TypeMember,
|
||||||
|
traits: []Trait,
|
||||||
|
},
|
||||||
|
unit: TraitsOnly,
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://awslabs.github.io/smithy/1.0/spec/aws/index.html
|
// https://awslabs.github.io/smithy/1.0/spec/aws/index.html
|
||||||
|
@ -266,7 +290,10 @@ fn shapes(allocator: std.mem.Allocator, map: anytype) ![]ShapeInfo {
|
||||||
.namespace = id_info.namespace,
|
.namespace = id_info.namespace,
|
||||||
.name = id_info.name,
|
.name = id_info.name,
|
||||||
.member = id_info.member,
|
.member = id_info.member,
|
||||||
.shape = try getShape(allocator, kv.value_ptr.*),
|
.shape = getShape(allocator, kv.value_ptr.*) catch |e| {
|
||||||
|
std.log.err("Caught error parsing shape with name {s}: {}", .{ id_info.name, e });
|
||||||
|
return e;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// This seems to be a synonym for the simple type "string"
|
// This seems to be a synonym for the simple type "string"
|
||||||
|
@ -328,6 +355,121 @@ fn shapes(allocator: std.mem.Allocator, map: anytype) ![]ShapeInfo {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#Blob",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "Blob",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.blob = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#Unit",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "Unit",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.unit = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#Long",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "Long",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.long = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#Float",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "Float",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.float = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#Document",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "Document",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.document = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// These "Primitive" versions only appear to differ in that they have defaults
|
||||||
|
// defined. Not currently handled:
|
||||||
|
// byte PrimitiveByte
|
||||||
|
// short PrimitiveShort
|
||||||
|
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#PrimitiveBoolean",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "PrimitiveBoolean",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.boolean = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#PrimitiveInteger",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "PrimitiveInteger",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.integer = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#PrimitiveDouble",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "PrimitiveDouble",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.double = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#PrimitiveLong",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "PrimitiveLong",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.long = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try list.append(.{
|
||||||
|
.id = "smithy.api#PrimitiveFloat",
|
||||||
|
.namespace = "smithy.api",
|
||||||
|
.name = "PrimitiveFloat",
|
||||||
|
.member = null,
|
||||||
|
.shape = Shape{
|
||||||
|
.float = .{
|
||||||
|
.traits = &.{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
return list.toOwnedSlice();
|
return list.toOwnedSlice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +568,13 @@ fn getShape(allocator: std.mem.Allocator, shape: std.json.Value) SmithyParseErro
|
||||||
return Shape{ .member = try parseTraitsOnly(allocator, shape) };
|
return Shape{ .member = try parseTraitsOnly(allocator, shape) };
|
||||||
if (std.mem.eql(u8, shape_type, "resource"))
|
if (std.mem.eql(u8, shape_type, "resource"))
|
||||||
return Shape{ .resource = try parseTraitsOnly(allocator, shape) };
|
return Shape{ .resource = try parseTraitsOnly(allocator, shape) };
|
||||||
|
if (std.mem.eql(u8, shape_type, "enum"))
|
||||||
|
return Shape{
|
||||||
|
.@"enum" = .{
|
||||||
|
.members = try parseMembers(allocator, shape.object.get("members")),
|
||||||
|
.traits = try parseTraits(allocator, shape.object.get("traits")),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
std.debug.print("Invalid Type: {s}", .{shape_type});
|
std.debug.print("Invalid Type: {s}", .{shape_type});
|
||||||
return SmithyParseError.InvalidType;
|
return SmithyParseError.InvalidType;
|
||||||
|
@ -486,9 +635,9 @@ fn getTrait(trait_type: []const u8, value: std.json.Value) SmithyParseError!?Tra
|
||||||
return Trait{
|
return Trait{
|
||||||
.aws_api_service = .{
|
.aws_api_service = .{
|
||||||
.sdk_id = value.object.get("sdkId").?.string,
|
.sdk_id = value.object.get("sdkId").?.string,
|
||||||
.arn_namespace = value.object.get("arnNamespace").?.string,
|
.arn_namespace = if (value.object.get("arnNamespace")) |a| a.string else null,
|
||||||
.cloudformation_name = value.object.get("cloudFormationName").?.string,
|
.cloudformation_name = if (value.object.get("cloudFormationName")) |n| n.string else null,
|
||||||
.cloudtrail_event_source = value.object.get("cloudTrailEventSource").?.string,
|
.cloudtrail_event_source = if (value.object.get("cloudTrailEventSource")) |s| s.string else null,
|
||||||
// what good is a service without an endpoint? I don't know - ask amp
|
// what good is a service without an endpoint? I don't know - ask amp
|
||||||
.endpoint_prefix = if (value.object.get("endpointPrefix")) |endpoint| endpoint.string else "",
|
.endpoint_prefix = if (value.object.get("endpointPrefix")) |endpoint| endpoint.string else "",
|
||||||
},
|
},
|
||||||
|
@ -501,6 +650,8 @@ fn getTrait(trait_type: []const u8, value: std.json.Value) SmithyParseError!?Tra
|
||||||
};
|
};
|
||||||
if (std.mem.eql(u8, trait_type, "smithy.api#required"))
|
if (std.mem.eql(u8, trait_type, "smithy.api#required"))
|
||||||
return Trait{ .required = .{} };
|
return Trait{ .required = .{} };
|
||||||
|
if (std.mem.eql(u8, trait_type, "smithy.api#clientOptional"))
|
||||||
|
return Trait{ .client_optional = {} };
|
||||||
if (std.mem.eql(u8, trait_type, "smithy.api#sparse"))
|
if (std.mem.eql(u8, trait_type, "smithy.api#sparse"))
|
||||||
return Trait{ .sparse = .{} };
|
return Trait{ .sparse = .{} };
|
||||||
if (std.mem.eql(u8, trait_type, "smithy.api#box"))
|
if (std.mem.eql(u8, trait_type, "smithy.api#box"))
|
||||||
|
@ -565,6 +716,14 @@ fn getTrait(trait_type: []const u8, value: std.json.Value) SmithyParseError!?Tra
|
||||||
.code = code,
|
.code = code,
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
|
if (std.mem.eql(u8, trait_type, "aws.protocols#awsQueryError")) {
|
||||||
|
return Trait{
|
||||||
|
.aws_query_error = .{
|
||||||
|
.code = value.object.get("code").?.string, // code is required
|
||||||
|
.http_response_code = value.object.get("httpResponseCode").?.integer,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
if (std.mem.eql(u8, trait_type, "smithy.api#jsonName"))
|
if (std.mem.eql(u8, trait_type, "smithy.api#jsonName"))
|
||||||
return Trait{ .json_name = value.string };
|
return Trait{ .json_name = value.string };
|
||||||
if (std.mem.eql(u8, trait_type, "smithy.api#xmlName"))
|
if (std.mem.eql(u8, trait_type, "smithy.api#xmlName"))
|
||||||
|
@ -582,6 +741,10 @@ fn getTrait(trait_type: []const u8, value: std.json.Value) SmithyParseError!?Tra
|
||||||
|
|
||||||
if (std.mem.eql(u8, trait_type, "smithy.api#xmlNamespace"))
|
if (std.mem.eql(u8, trait_type, "smithy.api#xmlNamespace"))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, trait_type, "smithy.api#enumValue"))
|
||||||
|
return Trait{ .enum_value = value.string };
|
||||||
|
|
||||||
// TODO: win argument with compiler to get this comptime
|
// TODO: win argument with compiler to get this comptime
|
||||||
const list =
|
const list =
|
||||||
\\aws.api#arnReference
|
\\aws.api#arnReference
|
||||||
|
@ -623,7 +786,45 @@ fn getTrait(trait_type: []const u8, value: std.json.Value) SmithyParseError!?Tra
|
||||||
\\smithy.api#xmlAttribute
|
\\smithy.api#xmlAttribute
|
||||||
\\smithy.api#xmlFlattened
|
\\smithy.api#xmlFlattened
|
||||||
\\smithy.waiters#waitable
|
\\smithy.waiters#waitable
|
||||||
;
|
\\smithy.rules#endpointTests
|
||||||
|
\\smithy.api#input
|
||||||
|
\\smithy.api#output
|
||||||
|
\\smithy.api#default
|
||||||
|
\\smithy.api#examples
|
||||||
|
\\smithy.api#uniqueItems
|
||||||
|
\\smithy.api#addedDefault
|
||||||
|
\\smithy.api#resourceIdentifier
|
||||||
|
\\smithy.api#unstable
|
||||||
|
\\smithy.api#property
|
||||||
|
\\smithy.api#notProperty
|
||||||
|
\\smithy.api#recommended
|
||||||
|
\\smithy.api#httpBearerAuth
|
||||||
|
\\smithy.api#nestedProperties
|
||||||
|
\\smithy.rules#endpointRuleSet
|
||||||
|
\\smithy.rules#contextParam
|
||||||
|
\\smithy.rules#clientContextParams
|
||||||
|
\\smithy.rules#staticContextParams
|
||||||
|
\\aws.cloudformation#cfnResource
|
||||||
|
\\aws.cloudformation#cfnMutability
|
||||||
|
\\aws.cloudformation#cfnExcludeProperty
|
||||||
|
\\aws.cloudformation#cfnAdditionalIdentifier
|
||||||
|
\\aws.iam#actionPermissionDescription
|
||||||
|
\\aws.iam#requiredActions
|
||||||
|
\\aws.iam#conditionKeys
|
||||||
|
\\aws.iam#iamResource
|
||||||
|
\\aws.iam#iamAction
|
||||||
|
\\aws.iam#supportedPrincipalTypes
|
||||||
|
\\aws.iam#defineConditionKeys
|
||||||
|
\\aws.iam#actionName
|
||||||
|
\\aws.api#data
|
||||||
|
\\aws.api#controlPlane
|
||||||
|
\\aws.api#dataPlane
|
||||||
|
\\aws.api#tagEnabled
|
||||||
|
\\aws.api#taggable
|
||||||
|
\\aws.protocols#awsQueryCompatible
|
||||||
|
\\aws.protocols#httpChecksum
|
||||||
|
\\aws.customizations#s3UnwrappedXmlOutput
|
||||||
|
; // NOTE: inputs/outputs are not used in AWS models, but default is and might be handy
|
||||||
var iterator = std.mem.split(u8, list, "\n");
|
var iterator = std.mem.split(u8, list, "\n");
|
||||||
while (iterator.next()) |known_but_unimplemented| {
|
while (iterator.next()) |known_but_unimplemented| {
|
||||||
if (std.mem.eql(u8, trait_type, known_but_unimplemented))
|
if (std.mem.eql(u8, trait_type, known_but_unimplemented))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user