refactor: extract date methods into shared date lib
This commit is contained in:
parent
0192c1e888
commit
29e9dd481b
10 changed files with 175 additions and 44 deletions
77
build.zig
77
build.zig
|
@ -19,14 +19,7 @@ const test_targets = [_]std.Target.Query{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn build(b: *Builder) !void {
|
pub fn build(b: *Builder) !void {
|
||||||
// Standard target options allows the person running `zig build` to choose
|
|
||||||
// what target to build for. Here we do not override the defaults, which
|
|
||||||
// means any target is allowed, and the default is native. Other options
|
|
||||||
// for restricting supported target set are available.
|
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
|
|
||||||
// Standard release options allow the person running `zig build` to select
|
|
||||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const no_llvm = b.option(
|
const no_llvm = b.option(
|
||||||
|
@ -46,6 +39,7 @@ pub fn build(b: *Builder) !void {
|
||||||
"test-filter",
|
"test-filter",
|
||||||
"Skip tests that do not match any of the specified filters",
|
"Skip tests that do not match any of the specified filters",
|
||||||
) orelse &.{};
|
) orelse &.{};
|
||||||
|
|
||||||
// TODO: Embed the current git version in the code. We can do this
|
// TODO: Embed the current git version in the code. We can do this
|
||||||
// by looking for .git/HEAD (if it exists, follow the ref to /ref/heads/whatevs,
|
// by looking for .git/HEAD (if it exists, follow the ref to /ref/heads/whatevs,
|
||||||
// grab that commit, and use b.addOptions/exe.addOptions to generate the
|
// grab that commit, and use b.addOptions/exe.addOptions to generate the
|
||||||
|
@ -58,13 +52,17 @@ pub fn build(b: *Builder) !void {
|
||||||
// executable
|
// executable
|
||||||
// TODO: This executable should not be built when importing as a package.
|
// TODO: This executable should not be built when importing as a package.
|
||||||
// It relies on code gen and is all fouled up when getting imported
|
// It relies on code gen and is all fouled up when getting imported
|
||||||
const exe = b.addExecutable(.{
|
const mod_exe = b.createModule(.{
|
||||||
.name = "demo",
|
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
exe.use_llvm = !no_llvm;
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "demo",
|
||||||
|
.root_module = mod_exe,
|
||||||
|
.use_llvm = !no_llvm,
|
||||||
|
});
|
||||||
|
|
||||||
// External dependencies
|
// External dependencies
|
||||||
const dep_smithy = b.dependency("smithy", .{
|
const dep_smithy = b.dependency("smithy", .{
|
||||||
|
@ -72,16 +70,31 @@ pub fn build(b: *Builder) !void {
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
const mod_smithy = dep_smithy.module("smithy");
|
const mod_smithy = dep_smithy.module("smithy");
|
||||||
exe.root_module.addImport("smithy", mod_smithy); // not sure this should be here...
|
mod_exe.addImport("smithy", mod_smithy); // not sure this should be here...
|
||||||
|
|
||||||
const dep_zeit = b.dependency("zeit", .{
|
const dep_zeit = b.dependency("zeit", .{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
const mod_zeit = dep_zeit.module("zeit");
|
const mod_zeit = dep_zeit.module("zeit");
|
||||||
exe.root_module.addImport("zeit", mod_zeit);
|
mod_exe.addImport("zeit", mod_zeit);
|
||||||
// End External dependencies
|
// End External dependencies
|
||||||
|
|
||||||
|
// Private modules/dependencies
|
||||||
|
const mod_json = b.createModule(.{
|
||||||
|
.root_source_file = b.path("codegen/src/json.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const dep_date = b.dependency("date", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
const mod_date = dep_date.module("date");
|
||||||
|
mod_exe.addImport("date", mod_date);
|
||||||
|
// End private modules/dependencies
|
||||||
|
|
||||||
const run_cmd = b.addRunArtifact(exe);
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
if (b.args) |args| {
|
if (b.args) |args| {
|
||||||
|
@ -93,14 +106,19 @@ pub fn build(b: *Builder) !void {
|
||||||
|
|
||||||
const cg = b.step("gen", "Generate zig service code from smithy models");
|
const cg = b.step("gen", "Generate zig service code from smithy models");
|
||||||
|
|
||||||
const cg_exe = b.addExecutable(.{
|
const cg_mod = b.createModule(.{
|
||||||
.name = "codegen",
|
|
||||||
.root_source_file = b.path("codegen/src/main.zig"),
|
.root_source_file = b.path("codegen/src/main.zig"),
|
||||||
// We need this generated for the host, not the real target
|
// We need this generated for the host, not the real target
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
.optimize = if (b.verbose) .Debug else .ReleaseSafe,
|
.optimize = if (b.verbose) .Debug else .ReleaseSafe,
|
||||||
});
|
});
|
||||||
cg_exe.root_module.addImport("smithy", mod_smithy);
|
cg_mod.addImport("smithy", mod_smithy);
|
||||||
|
cg_mod.addImport("date", mod_date);
|
||||||
|
|
||||||
|
const cg_exe = b.addExecutable(.{
|
||||||
|
.name = "codegen",
|
||||||
|
.root_module = cg_mod,
|
||||||
|
});
|
||||||
var cg_cmd = b.addRunArtifact(cg_exe);
|
var cg_cmd = b.addRunArtifact(cg_exe);
|
||||||
cg_cmd.addArg("--models");
|
cg_cmd.addArg("--models");
|
||||||
cg_cmd.addArg(try std.fs.path.join(
|
cg_cmd.addArg(try std.fs.path.join(
|
||||||
|
@ -133,21 +151,6 @@ pub fn build(b: *Builder) !void {
|
||||||
|
|
||||||
exe.step.dependOn(cg);
|
exe.step.dependOn(cg);
|
||||||
|
|
||||||
// Codegen private modules
|
|
||||||
const mod_json = b.createModule(.{
|
|
||||||
.root_source_file = b.path("codegen/src/json.zig"),
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
const mod_date = b.createModule(.{
|
|
||||||
.root_source_file = b.path("codegen/src/date.zig"),
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
mod_date.addImport("zeit", mod_zeit);
|
|
||||||
// End codegen private modules
|
|
||||||
|
|
||||||
// This allows us to have each module depend on the
|
// This allows us to have each module depend on the
|
||||||
// generated service manifest.
|
// generated service manifest.
|
||||||
const service_manifest_module = b.createModule(.{
|
const service_manifest_module = b.createModule(.{
|
||||||
|
@ -165,16 +168,20 @@ pub fn build(b: *Builder) !void {
|
||||||
// Expose module to others
|
// Expose module to others
|
||||||
const mod_aws = b.addModule("aws", .{
|
const mod_aws = b.addModule("aws", .{
|
||||||
.root_source_file = b.path("src/aws.zig"),
|
.root_source_file = b.path("src/aws.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
mod_aws.addImport("smithy", mod_smithy);
|
mod_aws.addImport("smithy", mod_smithy);
|
||||||
mod_aws.addImport("service_manifest", service_manifest_module);
|
mod_aws.addImport("service_manifest", service_manifest_module);
|
||||||
mod_aws.addImport("date", mod_date);
|
mod_aws.addImport("date", mod_date);
|
||||||
|
mod_aws.addImport("zeit", mod_zeit);
|
||||||
|
|
||||||
// Expose module to others
|
// Expose module to others
|
||||||
_ = b.addModule("aws-signing", .{
|
const mod_aws_signing = b.addModule("aws-signing", .{
|
||||||
.root_source_file = b.path("src/aws_signing.zig"),
|
.root_source_file = b.path("src/aws_signing.zig"),
|
||||||
.imports = &.{.{ .name = "smithy", .module = mod_smithy }},
|
|
||||||
});
|
});
|
||||||
|
mod_aws_signing.addImport("date", mod_date);
|
||||||
|
mod_aws_signing.addImport("smithy", mod_smithy);
|
||||||
|
|
||||||
// Similar to creating the run step earlier, this exposes a `test` step to
|
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||||
// the `zig build --help` menu, providing a way for the user to request
|
// the `zig build --help` menu, providing a way for the user to request
|
||||||
|
@ -234,14 +241,10 @@ pub fn build(b: *Builder) !void {
|
||||||
// Creates a step for unit testing. This only builds the test executable
|
// Creates a step for unit testing. This only builds the test executable
|
||||||
// but does not run it.
|
// but does not run it.
|
||||||
const smoke_test = b.addTest(.{
|
const smoke_test = b.addTest(.{
|
||||||
.root_source_file = b.path("src/aws.zig"),
|
.root_module = mod_aws,
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.filters = test_filters,
|
.filters = test_filters,
|
||||||
});
|
});
|
||||||
smoke_test.use_llvm = !no_llvm;
|
smoke_test.use_llvm = !no_llvm;
|
||||||
smoke_test.root_module.addImport("smithy", mod_smithy);
|
|
||||||
smoke_test.root_module.addImport("service_manifest", service_manifest_module);
|
|
||||||
smoke_test.step.dependOn(cg);
|
smoke_test.step.dependOn(cg);
|
||||||
|
|
||||||
const run_smoke_test = b.addRunArtifact(smoke_test);
|
const run_smoke_test = b.addRunArtifact(smoke_test);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"build.zig.zon",
|
"build.zig.zon",
|
||||||
"src",
|
"src",
|
||||||
"codegen",
|
"codegen",
|
||||||
|
"lib",
|
||||||
"README.md",
|
"README.md",
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
},
|
},
|
||||||
|
@ -24,5 +25,8 @@
|
||||||
.url = "git+https://github.com/rockorager/zeit#fb6557ad4bd0cd0f0f728ae978061d7fe992c528",
|
.url = "git+https://github.com/rockorager/zeit#fb6557ad4bd0cd0f0f728ae978061d7fe992c528",
|
||||||
.hash = "zeit-0.6.0-5I6bk29nAgDhK6AVMtXMWhkKTYgUncrWjnlI_8X9DPSd",
|
.hash = "zeit-0.6.0-5I6bk29nAgDhK6AVMtXMWhkKTYgUncrWjnlI_8X9DPSd",
|
||||||
},
|
},
|
||||||
|
.date = .{
|
||||||
|
.path = "lib/date",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
35
lib/date/build.zig
Normal file
35
lib/date/build.zig
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const lib_mod = b.addModule("date", .{
|
||||||
|
.root_source_file = b.path("src/root.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const lib = b.addLibrary(.{
|
||||||
|
.linkage = .static,
|
||||||
|
.name = "date",
|
||||||
|
.root_module = lib_mod,
|
||||||
|
});
|
||||||
|
|
||||||
|
b.installArtifact(lib);
|
||||||
|
|
||||||
|
const lib_unit_tests = b.addTest(.{
|
||||||
|
.root_module = lib_mod,
|
||||||
|
});
|
||||||
|
|
||||||
|
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||||
|
|
||||||
|
const test_step = b.step("test", "Run unit tests");
|
||||||
|
test_step.dependOn(&run_lib_unit_tests.step);
|
||||||
|
|
||||||
|
const dep_zeit = b.dependency("zeit", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
lib_mod.addImport("zeit", dep_zeit.module("zeit"));
|
||||||
|
}
|
17
lib/date/build.zig.zon
Normal file
17
lib/date/build.zig.zon
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
.{
|
||||||
|
.name = .date,
|
||||||
|
.version = "0.0.0",
|
||||||
|
.fingerprint = 0xaa9e377a226d739e, // Changing this has security and trust implications.
|
||||||
|
.minimum_zig_version = "0.14.0",
|
||||||
|
.dependencies = .{
|
||||||
|
.zeit = .{
|
||||||
|
.url = "git+https://github.com/rockorager/zeit#fb6557ad4bd0cd0f0f728ae978061d7fe992c528",
|
||||||
|
.hash = "zeit-0.6.0-5I6bk29nAgDhK6AVMtXMWhkKTYgUncrWjnlI_8X9DPSd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.paths = .{
|
||||||
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"src",
|
||||||
|
},
|
||||||
|
}
|
|
@ -3,12 +3,8 @@
|
||||||
// really requires the TZ DB.
|
// really requires the TZ DB.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const codegen_date = @import("date");
|
|
||||||
|
|
||||||
const log = std.log.scoped(.date);
|
const log = std.log.scoped(.date);
|
||||||
|
|
||||||
pub const Timestamp = codegen_date.Timestamp;
|
|
||||||
|
|
||||||
pub const DateTime = struct { day: u8, month: u8, year: u16, hour: u8, minute: u8, second: u8 };
|
pub const DateTime = struct { day: u8, month: u8, year: u16, hour: u8, minute: u8, second: u8 };
|
||||||
|
|
||||||
const SECONDS_PER_DAY = 86400; //* 24* 60 * 60 */
|
const SECONDS_PER_DAY = 86400; //* 24* 60 * 60 */
|
9
lib/date/src/root.zig
Normal file
9
lib/date/src/root.zig
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
pub usingnamespace @import("parsing.zig");
|
||||||
|
pub usingnamespace @import("timestamp.zig");
|
||||||
|
|
||||||
|
test {
|
||||||
|
testing.refAllDeclsRecursive(@This());
|
||||||
|
}
|
67
lib/date/src/timestamp.zig
Normal file
67
lib/date/src/timestamp.zig
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const zeit = @import("zeit");
|
||||||
|
|
||||||
|
pub const DateFormat = enum {
|
||||||
|
rfc1123,
|
||||||
|
iso8601,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Timestamp = enum(zeit.Nanoseconds) {
|
||||||
|
_,
|
||||||
|
|
||||||
|
pub fn jsonStringify(value: Timestamp, options: anytype, out_stream: anytype) !void {
|
||||||
|
_ = options;
|
||||||
|
|
||||||
|
const instant = try zeit.instant(.{
|
||||||
|
.source = .{
|
||||||
|
.unix_nano = @intFromEnum(value),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try out_stream.writeAll("\"");
|
||||||
|
try instant.time().gofmt(out_stream, "Mon, 02 Jan 2006 15:04:05 GMT");
|
||||||
|
try out_stream.writeAll("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(val: []const u8) !Timestamp {
|
||||||
|
const date_format = blk: {
|
||||||
|
if (std.ascii.isDigit(val[0])) {
|
||||||
|
break :blk DateFormat.iso8601;
|
||||||
|
} else {
|
||||||
|
break :blk DateFormat.rfc1123;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ins = try zeit.instant(.{
|
||||||
|
.source = switch (date_format) {
|
||||||
|
DateFormat.iso8601 => .{
|
||||||
|
.iso8601 = val,
|
||||||
|
},
|
||||||
|
DateFormat.rfc1123 => .{
|
||||||
|
.rfc1123 = val,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return @enumFromInt(ins.timestamp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test Timestamp {
|
||||||
|
const in_date = "Wed, 23 Apr 2025 11:23:45 GMT";
|
||||||
|
|
||||||
|
const expected_ts: Timestamp = @enumFromInt(1745407425000000000);
|
||||||
|
const actual_ts = try Timestamp.parse(in_date);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(expected_ts, actual_ts);
|
||||||
|
|
||||||
|
var buf: [100]u8 = undefined;
|
||||||
|
var fbs = std.io.fixedBufferStream(&buf);
|
||||||
|
var counting_writer = std.io.countingWriter(fbs.writer());
|
||||||
|
try Timestamp.jsonStringify(expected_ts, .{}, counting_writer.writer());
|
||||||
|
|
||||||
|
const expected_json = "\"" ++ in_date ++ "\"";
|
||||||
|
const actual_json = buf[0..counting_writer.bytes_written];
|
||||||
|
|
||||||
|
try std.testing.expectEqualStrings(expected_json, actual_json);
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ const awshttp = @import("aws_http.zig");
|
||||||
const json = @import("json.zig");
|
const json = @import("json.zig");
|
||||||
const url = @import("url.zig");
|
const url = @import("url.zig");
|
||||||
const case = @import("case.zig");
|
const case = @import("case.zig");
|
||||||
const date = @import("date.zig");
|
const date = @import("date");
|
||||||
const servicemodel = @import("servicemodel.zig");
|
const servicemodel = @import("servicemodel.zig");
|
||||||
const xml_shaper = @import("xml_shaper.zig");
|
const xml_shaper = @import("xml_shaper.zig");
|
||||||
const xml_serializer = @import("xml_serializer.zig");
|
const xml_serializer = @import("xml_serializer.zig");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const base = @import("aws_http_base.zig");
|
const base = @import("aws_http_base.zig");
|
||||||
const auth = @import("aws_authentication.zig");
|
const auth = @import("aws_authentication.zig");
|
||||||
const date = @import("date.zig");
|
const date = @import("date");
|
||||||
|
|
||||||
const scoped_log = std.log.scoped(.aws_signing);
|
const scoped_log = std.log.scoped(.aws_signing);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const xml = @import("xml.zig");
|
const xml = @import("xml.zig");
|
||||||
const date = @import("date.zig");
|
const date = @import("date");
|
||||||
|
|
||||||
const log = std.log.scoped(.xml_shaper);
|
const log = std.log.scoped(.xml_shaper);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue