diff --git a/src/Reader.zig b/src/Reader.zig index bce392f..fea9106 100644 --- a/src/Reader.zig +++ b/src/Reader.zig @@ -1478,6 +1478,31 @@ test skipElement { try expectEqual(.eof, try reader.read()); } +/// Reads and discards the rest of the document. +pub fn skipDocument(reader: *Reader) anyerror!void { + while (true) { + if (try reader.read() == .eof) return; + } +} + +test skipDocument { + var doc = StaticDocument.init( + \\ + \\ + \\ + \\ + ); + var reader = doc.reader(std.testing.allocator, .{}); + defer reader.deinit(); + + try expectEqual(.element_start, try reader.read()); + try expectEqualStrings("root", reader.elementName()); + try expectEqual(.element_end, try reader.read()); + try expectEqualStrings("root", reader.elementName()); + try reader.skipDocument(); + try expectEqual(.eof, try reader.read()); +} + fn readXmlDeclarationContent(reader: *Reader) !void { while (true) { try reader.readSpace(); diff --git a/src/xml.zig b/src/xml.zig index bfe4569..504c7ac 100644 --- a/src/xml.zig +++ b/src/xml.zig @@ -23,17 +23,43 @@ pub const Location = struct { } loc.column += s.len - pos; } + + pub fn format( + loc: Location, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) @TypeOf(writer).Error!void { + _ = fmt; + _ = options; + try writer.print("{}:{}", .{ loc.line, loc.column }); + } + + test format { + const loc: Location = .{ .line = 45, .column = 5 }; + var buf: [4]u8 = undefined; + const s = try std.fmt.bufPrint(&buf, "{}", .{loc}); + try expectEqualStrings("45:5", s); + } }; pub const QName = struct { ns: []const u8, local: []const u8, + + pub fn is(qname: QName, ns: []const u8, local: []const u8) bool { + return std.mem.eql(u8, qname.ns, ns) and std.mem.eql(u8, qname.local, local); + } }; pub const PrefixedQName = struct { prefix: []const u8, ns: []const u8, local: []const u8, + + pub fn is(qname: PrefixedQName, ns: []const u8, local: []const u8) bool { + return std.mem.eql(u8, qname.ns, ns) and std.mem.eql(u8, qname.local, local); + } }; pub const predefined_entities = std.StaticStringMap([]const u8).initComptime(.{ @@ -93,6 +119,11 @@ pub fn GenericReader(comptime SourceError: type) type { return @errorCast(reader.reader.skipElement()); } + /// See `Reader.skipDocument`. + pub inline fn skipDocument(reader: *@This()) ReadError!void { + return @errorCast(reader.reader.skipDocument()); + } + /// See `Reader.location`. pub inline fn location(reader: @This()) Location { return reader.reader.location(); @@ -471,6 +502,9 @@ pub fn streamingOutput(writer: anytype) StreamingOutput(@TypeOf(writer)) { } test { + _ = Location; + _ = QName; + _ = PrefixedQName; _ = Reader; _ = Writer; }