atproto pds in zig
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869const std = @import("std");const syntax = @import("syntax.zig");
pub const healthPath = "/xrpc/_health";
pub const Error = error{ NotXrpc, MissingMethod, InvalidMethod,};
pub const Method = struct { nsid: []const u8,
pub fn isHealth(self: Method) bool { return std.mem.eql(u8, self.nsid, "_health"); }};
pub fn parsePath(path: []const u8) Error!Method { const prefix = "/xrpc/"; if (!std.mem.startsWith(u8, path, prefix)) return Error.NotXrpc; const rest = path[prefix.len..]; if (rest.len == 0) return Error.MissingMethod; if (std.mem.indexOfScalar(u8, rest, '/') != null) return Error.InvalidMethod; if (std.mem.indexOfScalar(u8, rest, '?')) |query| { return parseMethod(rest[0..query]); } return parseMethod(rest);}
fn parseMethod(method: []const u8) Error!Method { if (std.mem.eql(u8, method, "_health")) return .{ .nsid = method }; syntax.validateNsid(method) catch return Error.InvalidMethod; return .{ .nsid = method };}
pub fn methodKind(method: []const u8) Error!enum { query, procedure, subscription, health } { const parsed = try parseMethod(method); if (parsed.isHealth()) return .health;
if (std.mem.endsWith(u8, method, "subscribeRepos")) return .subscription; if (std.mem.indexOf(u8, method, ".get") != null) return .query; if (std.mem.indexOf(u8, method, ".list") != null) return .query; if (std.mem.indexOf(u8, method, ".describe") != null) return .query; if (std.mem.indexOf(u8, method, ".resolve") != null) return .query; return .procedure;}
test "parses xrpc paths" { try std.testing.expect((try parsePath("/xrpc/_health")).isHealth()); try std.testing.expectEqualStrings("com.atproto.repo.getRecord", (try parsePath("/xrpc/com.atproto.repo.getRecord")).nsid);}
test "classifies method names" { try std.testing.expectEqual(.health, try methodKind("_health")); try std.testing.expectEqual(.query, try methodKind("com.atproto.repo.getRecord")); try std.testing.expectEqual(.query, try methodKind("com.atproto.repo.listRecords")); try std.testing.expectEqual(.subscription, try methodKind("com.atproto.sync.subscribeRepos")); try std.testing.expectEqual(.procedure, try methodKind("com.atproto.repo.createRecord"));}
test "rejects non-xrpc paths" { try std.testing.expectError(Error.NotXrpc, parsePath("/")); try std.testing.expectError(Error.MissingMethod, parsePath("/xrpc/")); try std.testing.expectError(Error.InvalidMethod, parsePath("/xrpc/com"));}