Function any [src]

Expect a value.

Prototype

pub fn any(self: *Decoder, comptime T: type) !T

Parameters

self: *DecoderT: type

Source

pub fn any(self: *Decoder, comptime T: type) !T { if (std.meta.hasFn(T, "decodeDer")) return try T.decodeDer(self); const tag = Tag.fromZig(T).toExpected(); switch (@typeInfo(T)) { .@"struct" => { const ele = try self.element(tag); defer self.index = ele.slice.end; // don't force parsing all fields var res: T = undefined; inline for (std.meta.fields(T)) |f| { self.field_tag = FieldTag.fromContainer(T, f.name); if (self.field_tag) |ft| { if (ft.explicit) { const seq = try self.element(ft.toTag().toExpected()); self.index = seq.slice.start; self.field_tag = null; } } @field(res, f.name) = self.any(f.type) catch |err| brk: { if (f.defaultValue()) |d| { break :brk d; } return err; }; // DER encodes null values by skipping them. if (@typeInfo(f.type) == .optional and @field(res, f.name) == null) { if (f.defaultValue()) |d| @field(res, f.name) = d; } } return res; }, .bool => { const ele = try self.element(tag); const bytes = self.view(ele); if (bytes.len != 1) return error.InvalidBool; return switch (bytes[0]) { 0x00 => false, 0xff => true, else => error.InvalidBool, }; }, .int => { const ele = try self.element(tag); const bytes = self.view(ele); return try int(T, bytes); }, .@"enum" => |e| { const ele = try self.element(tag); const bytes = self.view(ele); if (@hasDecl(T, "oids")) { return T.oids.oidToEnum(bytes) orelse return error.UnknownOid; } return @enumFromInt(try int(e.tag_type, bytes)); }, .optional => |o| return self.any(o.child) catch return null, else => @compileError("cannot decode type " ++ @typeName(T)), } }