Skip to content

Commit 815d223

Browse files
author
Javier Orfo
committed
init
1 parent 3b2b358 commit 815d223

File tree

7 files changed

+202
-1
lines changed

7 files changed

+202
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# zig-epub
2-
Zig library for creating EPUB files
2+
*Zig library for creating EPUB files*

build.zig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const std = @import("std");
2+
3+
pub fn build(b: *std.Build) void {
4+
const target = b.standardTargetOptions(.{});
5+
6+
const optimize = b.standardOptimizeOption(.{});
7+
8+
const lib = b.addStaticLibrary(.{
9+
.name = "zig-epub",
10+
.root_source_file = b.path("src/root.zig"),
11+
.target = target,
12+
.optimize = optimize,
13+
});
14+
15+
b.installArtifact(lib);
16+
17+
const lib_unit_tests = b.addTest(.{
18+
.root_source_file = b.path("src/root.zig"),
19+
.target = target,
20+
.optimize = optimize,
21+
});
22+
23+
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
24+
25+
const test_step = b.step("test", "Run unit tests");
26+
test_step.dependOn(&run_lib_unit_tests.step);
27+
}

build.zig.zon

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.{
2+
.name = "zig-epub",
3+
.version = "0.0.0",
4+
.minimum_zig_version = "0.13.0",
5+
.dependencies = .{},
6+
.paths = .{
7+
"build.zig",
8+
"build.zig.zon",
9+
"src",
10+
"LICENSE",
11+
"README.md",
12+
},
13+
}

src/Epub.zig

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const std = @import("std");
2+
const UUID = @import("UUID.zig");
3+
const Section = @import("Section.zig");
4+
const testing = std.testing;
5+
6+
allocator: std.mem.Allocator,
7+
metadata: Metadata,
8+
sections: ?[]Section = null,
9+
// TODO
10+
// stylesheets: []Stylesheet,
11+
// images: []Image,
12+
13+
const Epub = @This();
14+
15+
pub fn init(allocator: std.mem.Allocator, metadata: Metadata) Epub {
16+
return .{
17+
.allocator = allocator,
18+
.metadata = metadata,
19+
};
20+
}
21+
22+
const Metadata = struct {
23+
title: []const u8,
24+
creator: []const u8,
25+
identifier: []const u8,
26+
language: []const u8 = "en",
27+
date: ?[]const u8 = null,
28+
publisher: ?[]const u8 = null,
29+
};
30+
31+
test "epub" {
32+
const uuid = UUID.new();
33+
const epub = Epub.init(testing.allocator, .{ .title = "test", .creator = "John", .identifier = uuid });
34+
try testing.expect(@TypeOf(epub) == Epub);
35+
}

src/Section.zig

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
const std = @import("std");
2+
const testing = std.testing;
3+
4+
name: []const u8,
5+
content: Content,
6+
allocator: std.mem.Allocator,
7+
8+
const Section = @This();
9+
10+
pub fn init(allocator: std.mem.Allocator, name: []const u8, content: Content) Section {
11+
return .{
12+
.allocator = allocator,
13+
.name = name,
14+
.content = content,
15+
};
16+
}
17+
18+
const Content = union(enum) {
19+
raw: []const u8,
20+
file_path: []const u8,
21+
22+
pub fn get(self: Content, allocator: std.mem.Allocator) ![]const u8 {
23+
switch (self) {
24+
.file_path => |f| return try readFileToString(allocator, f),
25+
.raw => |r| return r,
26+
}
27+
}
28+
29+
fn readFileToString(allocator: std.mem.Allocator, file_path: []const u8) ![]const u8 {
30+
var file = try std.fs.openFileAbsolute(file_path, .{});
31+
defer file.close();
32+
33+
const file_size = try file.getEndPos();
34+
var buffer = try allocator.alloc(u8, file_size);
35+
errdefer allocator.free(buffer);
36+
37+
const read = try file.readAll(buffer);
38+
return buffer[0..read];
39+
}
40+
41+
pub fn isFile(self: Content) bool {
42+
switch (self) {
43+
.file_path => return true,
44+
.raw => return false,
45+
}
46+
}
47+
};
48+
49+
test "section raw" {
50+
const alloc = testing.allocator;
51+
52+
const raw =
53+
\\ <h1>Title</h2>
54+
\\ <p>Something</p>
55+
;
56+
57+
var section = Section.init(alloc, "chapter1", .{ .raw = raw });
58+
try testing.expectEqualStrings(raw, try section.content.get(alloc));
59+
}
60+
61+
test "section file" {
62+
const alloc = testing.allocator;
63+
64+
const cwd_path = try std.fs.cwd().realpathAlloc(alloc, ".");
65+
defer alloc.free(cwd_path);
66+
const absolute_path = try std.fs.path.resolve(alloc, &.{ cwd_path, "README.md" });
67+
defer alloc.free(absolute_path);
68+
69+
var section = Section.init(alloc, "chapter2", .{ .file_path = absolute_path });
70+
const value = try section.content.get(alloc);
71+
defer alloc.free(value);
72+
try testing.expectEqualStrings("zig-epub", value[2..10]);
73+
}
74+
75+
test "section file error" {
76+
const alloc = testing.allocator;
77+
var section = Section.init(alloc, "chapter3", .{ .file_path = "/no_existent" });
78+
try testing.expectError(error.FileNotFound, section.content.get(alloc));
79+
}

src/UUID.zig

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const std = @import("std");
2+
3+
const encoded_pos = [16]u8{ 0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34 };
4+
const hex = "0123456789abcdef";
5+
6+
const UUID = @This();
7+
8+
pub fn new() []const u8 {
9+
var bytes: [16]u8 = undefined;
10+
const seed: u64 = @intCast(@as(i128, @bitCast(std.time.nanoTimestamp())));
11+
var prng = std.rand.DefaultPrng.init(seed);
12+
prng.random().bytes(&bytes);
13+
14+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
15+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
16+
17+
var buffer: [36]u8 = undefined;
18+
buffer[8] = '-';
19+
buffer[13] = '-';
20+
buffer[18] = '-';
21+
buffer[23] = '-';
22+
inline for (encoded_pos, 0..) |i, j| {
23+
buffer[i + 0] = hex[bytes[j] >> 4];
24+
buffer[i + 1] = hex[bytes[j] & 0x0f];
25+
}
26+
27+
return &buffer;
28+
}
29+
30+
test "uuid" {
31+
const uuid = UUID.new();
32+
try std.testing.expect(uuid.len == 36);
33+
try std.testing.expect(uuid[8] == '-');
34+
try std.testing.expect(uuid[13] == '-');
35+
try std.testing.expect(uuid[18] == '-');
36+
try std.testing.expect(uuid[23] == '-');
37+
}

src/root.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const std = @import("std");
2+
const testing = std.testing;
3+
4+
pub const Epub = @import("Epub.zig");
5+
pub const Section = @import("Section.zig");
6+
pub const UUID = @import("UUID.zig");
7+
8+
test {
9+
testing.refAllDecls(@This());
10+
}

0 commit comments

Comments
 (0)