aboutsummaryrefslogtreecommitdiff
path: root/src/tags/Use.zig
blob: 6ba1b1b30fe3cea10f37ee5315aeeb70a2483dc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
const std = @import("std");
const Io = std.Io;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
const SplitIterator = std.mem.SplitIterator;
const DelimiterType = std.mem.DelimiterType;

const parser = @import("../root.zig");
const Parser = parser.Parser;

pub const UseTagError = error{ NoPartAttribute, NoPartExported };

pub const Use: parser.ParserTag = .{
    .name = "use",
    .parse_fn = &parse,
};

fn parse(
    arena: *ArenaAllocator,
    io: Io,
    state: *Parser,
    reader: *Io.Reader,
    writer: *Io.Writer,
    attrs: *SplitIterator(u8, DelimiterType.scalar),
) anyerror!void {
    _ = io;

    const raw_part_attr: []const u8 = while (attrs.next()) |attr| {
        var it = std.mem.splitScalar(u8, attr, '=');
        if (std.mem.eql(u8, it.first(), "part")) {
            break it.next() orelse return UseTagError.NoPartAttribute;
        }
    } else return UseTagError.NoPartAttribute;

    const part = try arena.allocator().dupe(u8, raw_part_attr);

    const part_text = state.exported_parts.get(part) orelse return UseTagError.NoPartExported;

    var part_reader = Io.Reader.fixed(part_text);

    _ = try part_reader.streamRemaining(writer);

    while (true) {
        _ = try reader.discardDelimiterInclusive('<');
        const inside = try reader.takeDelimiterInclusive('>');
        if (std.mem.eql(u8, "/use>", inside)) return;
    }
}