an atproto pds written in F# (.NET 9) 馃
pds fsharp giraffe dotnet atproto
at main 1.4 kB view raw
1namespace PDSharp.Core 2 3open System 4open System.Text.RegularExpressions 5 6/// AT-URI parsing and validation 7module AtUri = 8 /// Represents an AT Protocol URI: at://did/collection/rkey 9 type AtUri = { Did : string; Collection : string; Rkey : string } 10 11 let private didPattern = @"^did:[a-z]+:[a-zA-Z0-9._:%-]+$" 12 let private nsidPattern = @"^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)+$" 13 let private rkeyPattern = @"^[a-zA-Z0-9._~-]+$" 14 15 /// Parse an AT-URI string into components 16 let parse (uri : string) : Result<AtUri, string> = 17 if not (uri.StartsWith("at://")) then 18 Error "AT-URI must start with at://" 19 else 20 let path = uri.Substring(5) 21 let parts = path.Split('/') 22 23 if parts.Length < 3 then 24 Error "AT-URI must have format at://did/collection/rkey" 25 else 26 let did = parts.[0] 27 let collection = parts.[1] 28 let rkey = parts.[2] 29 30 if not (Regex.IsMatch(did, didPattern)) then 31 Error $"Invalid DID format: {did}" 32 elif not (Regex.IsMatch(collection, nsidPattern)) then 33 Error $"Invalid collection NSID: {collection}" 34 elif not (Regex.IsMatch(rkey, rkeyPattern)) then 35 Error $"Invalid rkey format: {rkey}" 36 else 37 Ok { Did = did; Collection = collection; Rkey = rkey } 38 39 /// Convert AtUri back to string 40 let toString (uri : AtUri) : string = 41 $"at://{uri.Did}/{uri.Collection}/{uri.Rkey}"