Compare commits
No commits in common. "16fd5b0b958016e0a3f49d31c839477cf1afa3df" and "cb4a4aed9ea3e5bb0bc3c7df0fce194fd312dccc" have entirely different histories.
16fd5b0b95
...
cb4a4aed9e
14
flake.lock
generated
|
@ -54,16 +54,16 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1750259320,
|
"lastModified": 1749995256,
|
||||||
"narHash": "sha256-H8J4H2XCIMEJ5g6fZ179QfQvsc2dUqhqfBjC8RAHNRY=",
|
"narHash": "sha256-LEGfcombb0otUf23oAmYCXR4+lMQKa49XmU0G5HItGI=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9ba04bda9249d5d5e5238303c9755de5a49a79c5",
|
"rev": "daa45f10955cc2207ac9c5f0206774d2f757c162",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-25.05",
|
"ref": "nixos-24.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
@ -128,11 +128,11 @@
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1750379715,
|
"lastModified": 1750293335,
|
||||||
"narHash": "sha256-R7yDQlTHvARic5adjg7e/rT22m0mDME90mEgGM6thic=",
|
"narHash": "sha256-qAX+hIcUqVl8BzLHTRBrceF2vGeht+gfhvvUZgKe/98=",
|
||||||
"owner": "mitchellh",
|
"owner": "mitchellh",
|
||||||
"repo": "zig-overlay",
|
"repo": "zig-overlay",
|
||||||
"rev": "f69e9790793d81a8f32af8426008cb2a3871bad5",
|
"rev": "3453b39a83069811d077a0bc696849c6907112d5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
|
||||||
flake-utils.url = "github:/numtide/flake-utils";
|
flake-utils.url = "github:/numtide/flake-utils";
|
||||||
zig.url = "github:mitchellh/zig-overlay";
|
zig.url = "github:mitchellh/zig-overlay";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
pub const TransportationProductClass = enum(u32) {
|
|
||||||
zug = 0,
|
|
||||||
s_bahn = 1,
|
|
||||||
u_bahn = 2,
|
|
||||||
stadtbahn = 3,
|
|
||||||
strassen_trambahn = 4,
|
|
||||||
stadtbus = 5,
|
|
||||||
regionalbus = 6,
|
|
||||||
schnellbus = 7,
|
|
||||||
seil_zahnradbahn = 8,
|
|
||||||
schiff = 9,
|
|
||||||
anruf_sammel_taxi = 10,
|
|
||||||
sonstige = 11,
|
|
||||||
flugzeug = 12,
|
|
||||||
zug_nv = 13,
|
|
||||||
zug_fv = 14,
|
|
||||||
zug_fv_m_zuschlag = 15,
|
|
||||||
zug_fv_m_spez_fpr = 16,
|
|
||||||
sev = 17,
|
|
||||||
zug_shuttle = 18,
|
|
||||||
buergerbus = 19,
|
|
||||||
rufbus_liniengebunden = 20,
|
|
||||||
rufbus = 21,
|
|
||||||
_,
|
|
||||||
|
|
||||||
pub fn toString(self: TransportationProductClass) ?[]const u8 {
|
|
||||||
return switch (self) {
|
|
||||||
.zug => "Zug",
|
|
||||||
.s_bahn => "S-Bahn",
|
|
||||||
.u_bahn => "U-Bahn",
|
|
||||||
.stadtbahn => "Stadtbahn",
|
|
||||||
.strassen_trambahn => "Straßen-/Trambahn",
|
|
||||||
.stadtbus => "Stadtbus",
|
|
||||||
.regionalbus => "Regionalbus",
|
|
||||||
.schnellbus => "Schnellbus",
|
|
||||||
.seil_zahnradbahn => "Seil-/Zahnradbahn",
|
|
||||||
.schiff => "Schiff",
|
|
||||||
.anruf_sammel_taxi => "Anruf-Sammel-Taxi",
|
|
||||||
.sonstige => "Sonstige",
|
|
||||||
.flugzeug => "Flugzeug",
|
|
||||||
.zug_nv => "Zug (Nahverkehr)",
|
|
||||||
.zug_fv => "Zug (Fernverkehr)",
|
|
||||||
.zug_fv_m_zuschlag => "Zug (Fernverkehr) mit Zuschlag",
|
|
||||||
.zug_fv_m_spez_fpr => "Zug (Fernverkehr) mit spezifischer Fpr",
|
|
||||||
.sev => "SEV Schnienenersatzverkehr",
|
|
||||||
.zug_shuttle => "Zug Shuttle",
|
|
||||||
.buergerbus => "Bürgerbus",
|
|
||||||
.rufbus_liniengebunden => "Rufbus (liniengebunden)",
|
|
||||||
.rufbus => "Rufbus",
|
|
||||||
_ => null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Location = struct {
|
|
||||||
id: []const u8,
|
|
||||||
name: []const u8,
|
|
||||||
properties: struct {
|
|
||||||
platform: ?[]const u8 = null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const StopEvent = struct {
|
|
||||||
location: Location,
|
|
||||||
departureTimePlanned: []const u8,
|
|
||||||
departureTimeBaseTimetable: []const u8,
|
|
||||||
departureTimeEstimated: ?[]const u8 = null,
|
|
||||||
transportation: struct {
|
|
||||||
name: []const u8,
|
|
||||||
product: struct {
|
|
||||||
class: TransportationProductClass,
|
|
||||||
},
|
|
||||||
operator: ?struct {
|
|
||||||
name: []const u8,
|
|
||||||
} = null,
|
|
||||||
destination: struct {
|
|
||||||
name: []const u8,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
hints: ?[]const struct {
|
|
||||||
content: []const u8,
|
|
||||||
type: []const u8,
|
|
||||||
} = null,
|
|
||||||
isCancelled: bool = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const DmResponse = struct {
|
|
||||||
locations: []const Location,
|
|
||||||
stopEvents: []const StopEvent,
|
|
||||||
};
|
|
|
@ -1 +0,0 @@
|
||||||
pub const efa = @import("efa/root.zig");
|
|
|
@ -2,10 +2,99 @@ const std = @import("std");
|
||||||
|
|
||||||
const escaper = @import("../../escaper.zig");
|
const escaper = @import("../../escaper.zig");
|
||||||
|
|
||||||
pub const models = @import("models.zig");
|
|
||||||
|
|
||||||
const log = std.log.scoped(.efa);
|
const log = std.log.scoped(.efa);
|
||||||
|
|
||||||
|
pub const ApiTransportationProductClass = enum(u32) {
|
||||||
|
zug = 0,
|
||||||
|
s_bahn = 1,
|
||||||
|
u_bahn = 2,
|
||||||
|
stadtbahn = 3,
|
||||||
|
strassen_trambahn = 4,
|
||||||
|
stadtbus = 5,
|
||||||
|
regionalbus = 6,
|
||||||
|
schnellbus = 7,
|
||||||
|
seil_zahnradbahn = 8,
|
||||||
|
schiff = 9,
|
||||||
|
anruf_sammel_taxi = 10,
|
||||||
|
sonstige = 11,
|
||||||
|
flugzeug = 12,
|
||||||
|
zug_nv = 13,
|
||||||
|
zug_fv = 14,
|
||||||
|
zug_fv_m_zuschlag = 15,
|
||||||
|
zug_fv_m_spez_fpr = 16,
|
||||||
|
sev = 17,
|
||||||
|
zug_shuttle = 18,
|
||||||
|
buergerbus = 19,
|
||||||
|
rufbus_liniengebunden = 20,
|
||||||
|
rufbus = 21,
|
||||||
|
_,
|
||||||
|
|
||||||
|
pub fn toString(self: ApiTransportationProductClass) ?[]const u8 {
|
||||||
|
return switch (self) {
|
||||||
|
.zug => "Zug",
|
||||||
|
.s_bahn => "S-Bahn",
|
||||||
|
.u_bahn => "U-Bahn",
|
||||||
|
.stadtbahn => "Stadtbahn",
|
||||||
|
.strassen_trambahn => "Straßen-/Trambahn",
|
||||||
|
.stadtbus => "Stadtbus",
|
||||||
|
.regionalbus => "Regionalbus",
|
||||||
|
.schnellbus => "Schnellbus",
|
||||||
|
.seil_zahnradbahn => "Seil-/Zahnradbahn",
|
||||||
|
.schiff => "Schiff",
|
||||||
|
.anruf_sammel_taxi => "Anruf-Sammel-Taxi",
|
||||||
|
.sonstige => "Sonstige",
|
||||||
|
.flugzeug => "Flugzeug",
|
||||||
|
.zug_nv => "Zug (Nahverkehr)",
|
||||||
|
.zug_fv => "Zug (Fernverkehr)",
|
||||||
|
.zug_fv_m_zuschlag => "Zug (Fernverkehr) mit Zuschlag",
|
||||||
|
.zug_fv_m_spez_fpr => "Zug (Fernverkehr) mit spezifischer Fpr",
|
||||||
|
.sev => "SEV Schnienenersatzverkehr",
|
||||||
|
.zug_shuttle => "Zug Shuttle",
|
||||||
|
.buergerbus => "Bürgerbus",
|
||||||
|
.rufbus_liniengebunden => "Rufbus (liniengebunden)",
|
||||||
|
.rufbus => "Rufbus",
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ApiLocation = struct {
|
||||||
|
id: []const u8,
|
||||||
|
name: []const u8,
|
||||||
|
properties: struct {
|
||||||
|
platform: ?[]const u8 = null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ApiStopEvent = struct {
|
||||||
|
location: ApiLocation,
|
||||||
|
departureTimePlanned: []const u8,
|
||||||
|
departureTimeBaseTimetable: []const u8,
|
||||||
|
departureTimeEstimated: ?[]const u8 = null,
|
||||||
|
transportation: struct {
|
||||||
|
name: []const u8,
|
||||||
|
product: struct {
|
||||||
|
class: ApiTransportationProductClass,
|
||||||
|
},
|
||||||
|
operator: ?struct {
|
||||||
|
name: []const u8,
|
||||||
|
} = null,
|
||||||
|
destination: struct {
|
||||||
|
name: []const u8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hints: ?[]const struct {
|
||||||
|
content: []const u8,
|
||||||
|
type: []const u8,
|
||||||
|
} = null,
|
||||||
|
isCancelled: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DmResponse = struct {
|
||||||
|
locations: []const ApiLocation,
|
||||||
|
stopEvents: []const ApiStopEvent,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Client = struct {
|
pub const Client = struct {
|
||||||
pub const Error = error{
|
pub const Error = error{
|
||||||
InvalidResponse,
|
InvalidResponse,
|
||||||
|
@ -81,7 +170,7 @@ pub const Client = struct {
|
||||||
try std.io.getStdOut().writeAll(body);
|
try std.io.getStdOut().writeAll(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDepartures(self: *const Self, stop_id: []const u8) !std.json.Parsed(models.DmResponse) {
|
pub fn getDepartures(self: *const Self, stop_id: []const u8) !std.json.Parsed(DmResponse) {
|
||||||
const escaped_stop_id = try escaper.escapeUriComponent(self.allocator, stop_id);
|
const escaped_stop_id = try escaper.escapeUriComponent(self.allocator, stop_id);
|
||||||
defer if (escaped_stop_id) |s| self.allocator.free(s);
|
defer if (escaped_stop_id) |s| self.allocator.free(s);
|
||||||
const url_stop_id = escaped_stop_id orelse stop_id;
|
const url_stop_id = escaped_stop_id orelse stop_id;
|
||||||
|
@ -115,7 +204,7 @@ pub const Client = struct {
|
||||||
defer self.allocator.free(body);
|
defer self.allocator.free(body);
|
||||||
|
|
||||||
const response = try std.json.parseFromSlice(
|
const response = try std.json.parseFromSlice(
|
||||||
models.DmResponse,
|
DmResponse,
|
||||||
self.allocator,
|
self.allocator,
|
||||||
body,
|
body,
|
||||||
.{ .allocate = .alloc_always, .ignore_unknown_fields = true },
|
.{ .allocate = .alloc_always, .ignore_unknown_fields = true },
|
|
@ -5,7 +5,7 @@ const zdt = @import("zdt");
|
||||||
const Dimensions = @import("../../Dimensions.zig");
|
const Dimensions = @import("../../Dimensions.zig");
|
||||||
const renderer = @import("../../renderer.zig");
|
const renderer = @import("../../renderer.zig");
|
||||||
|
|
||||||
pub const api = @import("../../api/root.zig");
|
pub const efa = @import("efa.zig");
|
||||||
|
|
||||||
const template = @import("template/root.zig");
|
const template = @import("template/root.zig");
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ pub const RenderOptions = struct {
|
||||||
show_operator: bool,
|
show_operator: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn render(self: *const Self, efa_dm_resp: *const api.efa.models.DmResponse, options: RenderOptions) ![]const u8 {
|
pub fn render(self: *const Self, efa_dm_resp: *const efa.DmResponse, options: RenderOptions) ![]const u8 {
|
||||||
const now_local = try options.now.tzConvert(.{ .tz = options.tz });
|
const now_local = try options.now.tzConvert(.{ .tz = options.tz });
|
||||||
|
|
||||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||||
|
|
BIN
src/eink_feed_render/apps/Departures/template/icons/img/boat.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
src/eink_feed_render/apps/Departures/template/icons/img/bus.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
BIN
src/eink_feed_render/apps/Departures/template/icons/img/tram.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
|
@ -1,31 +1,8 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const api = @import("../../../../api/root.zig");
|
const efa = @import("../../efa.zig");
|
||||||
const embed = @import("../../../../embed.zig");
|
|
||||||
|
|
||||||
pub const data = embed.embedBase64Files(
|
pub fn iconFromTransportationProductClass(class: efa.ApiTransportationProductClass) ?[]const u8 {
|
||||||
(struct {
|
|
||||||
fn inner(comptime path: []const u8) []const u8 {
|
|
||||||
return @embedFile(path);
|
|
||||||
}
|
|
||||||
}).inner,
|
|
||||||
"image/svg+xml",
|
|
||||||
"svg",
|
|
||||||
"svg",
|
|
||||||
&.{
|
|
||||||
"train",
|
|
||||||
"subway",
|
|
||||||
"tram",
|
|
||||||
"bus",
|
|
||||||
"shuttle",
|
|
||||||
"gondola",
|
|
||||||
"flight",
|
|
||||||
"boat",
|
|
||||||
"no_transfer",
|
|
||||||
},
|
|
||||||
){};
|
|
||||||
|
|
||||||
pub fn iconFromTransportationProductClass(class: api.efa.models.TransportationProductClass) ?embed.EncodedFile {
|
|
||||||
return switch (class) {
|
return switch (class) {
|
||||||
.zug,
|
.zug,
|
||||||
.s_bahn,
|
.s_bahn,
|
||||||
|
@ -34,11 +11,11 @@ pub fn iconFromTransportationProductClass(class: api.efa.models.TransportationPr
|
||||||
.zug_fv_m_zuschlag,
|
.zug_fv_m_zuschlag,
|
||||||
.zug_fv_m_spez_fpr,
|
.zug_fv_m_spez_fpr,
|
||||||
.zug_shuttle,
|
.zug_shuttle,
|
||||||
=> data.train,
|
=> train,
|
||||||
|
|
||||||
.u_bahn => data.subway,
|
.u_bahn => subway,
|
||||||
|
|
||||||
.stadtbahn, .strassen_trambahn => data.tram,
|
.stadtbahn, .strassen_trambahn => tram,
|
||||||
|
|
||||||
.stadtbus,
|
.stadtbus,
|
||||||
.regionalbus,
|
.regionalbus,
|
||||||
|
@ -47,18 +24,40 @@ pub fn iconFromTransportationProductClass(class: api.efa.models.TransportationPr
|
||||||
.rufbus_liniengebunden,
|
.rufbus_liniengebunden,
|
||||||
.rufbus,
|
.rufbus,
|
||||||
.anruf_sammel_taxi,
|
.anruf_sammel_taxi,
|
||||||
=> data.bus,
|
=> bus,
|
||||||
|
|
||||||
.seil_zahnradbahn => data.gondola,
|
.seil_zahnradbahn => gondola,
|
||||||
|
|
||||||
.schiff => data.boat,
|
.schiff => boat,
|
||||||
|
|
||||||
.sonstige => null,
|
.sonstige => null,
|
||||||
|
|
||||||
.flugzeug => data.flight,
|
.flugzeug => flight,
|
||||||
|
|
||||||
.sev => data.no_transfer,
|
.sev => no_transfer,
|
||||||
|
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encodePng(comptime path: []const u8) []const u8 {
|
||||||
|
const raw = @embedFile(path);
|
||||||
|
const len = std.base64.standard.Encoder.calcSize(raw.len);
|
||||||
|
var buf: [len]u8 = undefined;
|
||||||
|
{
|
||||||
|
@setEvalBranchQuota(1_000_000);
|
||||||
|
_ = std.base64.standard.Encoder.encode(&buf, raw);
|
||||||
|
}
|
||||||
|
const final = buf;
|
||||||
|
return &final;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const train = encodePng("img/train.png");
|
||||||
|
pub const subway = encodePng("img/subway.png");
|
||||||
|
pub const tram = encodePng("img/tram.png");
|
||||||
|
pub const bus = encodePng("img/bus.png");
|
||||||
|
pub const shuttle = encodePng("img/shuttle.png");
|
||||||
|
pub const gondola = encodePng("img/gondola.png");
|
||||||
|
pub const flight = encodePng("img/flight.png");
|
||||||
|
pub const boat = encodePng("img/boat.png");
|
||||||
|
pub const no_transfer = encodePng("img/no_transfer.png");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const escaper = @import("../../../escaper.zig");
|
const escaper = @import("../../../escaper.zig");
|
||||||
const api = @import("../../../api/root.zig");
|
const efa = @import("../efa.zig");
|
||||||
|
|
||||||
const icons = @import("icons/root.zig");
|
const icons = @import("icons/root.zig");
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ pub const Departure = struct {
|
||||||
time: []const u8,
|
time: []const u8,
|
||||||
time_unix: i128,
|
time_unix: i128,
|
||||||
line: []const u8,
|
line: []const u8,
|
||||||
transportation_product_class: api.efa.models.TransportationProductClass,
|
transportation_product_class: efa.ApiTransportationProductClass,
|
||||||
operator: ?[]const u8,
|
operator: ?[]const u8,
|
||||||
destination: []const u8,
|
destination: []const u8,
|
||||||
platform: ?[]const u8,
|
platform: ?[]const u8,
|
||||||
|
@ -188,16 +188,13 @@ pub fn render(context: *const Context, writer: anytype) !void {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icons.iconFromTransportationProductClass(departure.transportation_product_class)) |file| {
|
if (icons.iconFromTransportationProductClass(departure.transportation_product_class)) |img| {
|
||||||
try writer.print(
|
try writer.print(
|
||||||
\\ <td>
|
\\ <td>
|
||||||
\\ <img class="icon" src="data:{[content_type]s};charset=utf-8;base64,{[data]s}" />
|
\\ <img class="icon" src="data:image/png;charset=utf-8;base64,{[img]s}" />
|
||||||
\\ </td>
|
\\ </td>
|
||||||
,
|
,
|
||||||
.{
|
.{ .img = img },
|
||||||
.content_type = file.content_type,
|
|
||||||
.data = file.data,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
try writer.writeAll(
|
try writer.writeAll(
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub const EncodedFile = struct {
|
|
||||||
content_type: []const u8,
|
|
||||||
data: []const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const EmbedFn = *const fn (comptime path: []const u8) []const u8;
|
|
||||||
|
|
||||||
pub fn encodeFileBase64(
|
|
||||||
comptime embed_fn: EmbedFn,
|
|
||||||
comptime content_type: []const u8,
|
|
||||||
comptime path: []const u8,
|
|
||||||
) EncodedFile {
|
|
||||||
const raw = embed_fn(path);
|
|
||||||
const len = std.base64.standard.Encoder.calcSize(raw.len);
|
|
||||||
var buf: [len]u8 = undefined;
|
|
||||||
{
|
|
||||||
@setEvalBranchQuota(1_000_000);
|
|
||||||
_ = std.base64.standard.Encoder.encode(&buf, raw);
|
|
||||||
}
|
|
||||||
const final = buf;
|
|
||||||
|
|
||||||
return .{
|
|
||||||
.content_type = content_type,
|
|
||||||
.data = &final,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn embedBase64Files(
|
|
||||||
comptime embed_fn: EmbedFn,
|
|
||||||
comptime content_type: []const u8,
|
|
||||||
comptime extension: []const u8,
|
|
||||||
comptime path: []const u8,
|
|
||||||
comptime names: []const []const u8,
|
|
||||||
) type {
|
|
||||||
var fields: [names.len]std.builtin.Type.StructField = undefined;
|
|
||||||
|
|
||||||
for (names, 0..) |name, i| {
|
|
||||||
const encoded = encodeFileBase64(
|
|
||||||
embed_fn,
|
|
||||||
content_type,
|
|
||||||
std.fmt.comptimePrint(
|
|
||||||
"{s}/{s}.{s}",
|
|
||||||
.{ path, name, extension },
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
var name_z: [name.len:0]u8 = undefined;
|
|
||||||
@memcpy(&name_z, name);
|
|
||||||
|
|
||||||
fields[i] = std.builtin.Type.StructField{
|
|
||||||
.name = &name_z,
|
|
||||||
.type = EncodedFile,
|
|
||||||
.is_comptime = true,
|
|
||||||
.alignment = 0,
|
|
||||||
.default_value_ptr = &encoded,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return @Type(.{ .@"struct" = .{
|
|
||||||
.layout = .auto,
|
|
||||||
.is_tuple = false,
|
|
||||||
.fields = &fields,
|
|
||||||
.decls = &[_]std.builtin.Type.Declaration{},
|
|
||||||
} });
|
|
||||||
}
|
|
|
@ -52,7 +52,7 @@ pub fn main() !void {
|
||||||
return clap.help(writer, clap.Help, ¶ms, .{});
|
return clap.help(writer, clap.Help, ¶ms, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
const efa = try render.api.efa.Client.init(allocator, res.args.efa.?);
|
const efa = try render.apps.Departures.efa.Client.init(allocator, res.args.efa.?);
|
||||||
defer efa.deinit();
|
defer efa.deinit();
|
||||||
|
|
||||||
if (res.args.stopfinder) |query| {
|
if (res.args.stopfinder) |query| {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
pub const api = @import("api/root.zig");
|
|
||||||
pub const apps = @import("apps/root.zig");
|
pub const apps = @import("apps/root.zig");
|
||||||
pub const renderer = @import("renderer.zig");
|
pub const renderer = @import("renderer.zig");
|
||||||
pub const FeedClient = @import("FeedClient.zig");
|
pub const FeedClient = @import("FeedClient.zig");
|
||||||
|
|