[WIP] A (somewhat barebones) atproto app for creating custom sites without hosting!
at main 2.1 kB view raw
1use regex::Regex; 2 3#[allow(dead_code)] 4pub fn rkey_to_url(rkey: String) -> Option<String> { 5 let regex = Regex::new( 6 // symbols A-Za-z0-9 -._~: are all valid rkey characters 7 // however we use a subset of record keys where : is an escape character 8 // allow any rkey character except colons 9 // or any of the valid escape sequences 10 // from start of string to end between 0 and unlimited times 11 r"^(?:[A-Za-z0-9.\-_~]|(?:::)|(?::~)|(?::21)|(?::24)|(?::26)|(?::27)|(?::28)|(?::29)|(?::2A)|(?::2B)|(?::2C)|(?::3A)|(?::3B)|(?::3D)|(?::40))*$", 12 ) 13 .expect("Regex failed to generate"); 14 15 if !regex.is_match(&rkey) { 16 return None; 17 }; 18 19 let res = rkey 20 .replace("::", "/") 21 .replace(":~", "%") 22 .replace(":21", "!") 23 .replace(":24", "$") 24 .replace(":26", "&") 25 .replace(":27", "'") 26 .replace(":28", "(") 27 .replace(":29", ")") 28 .replace(":2A", "*") 29 .replace(":2B", "+") 30 .replace(":2C", ",") 31 .replace(":3A", ":") 32 .replace(":3B", ";") 33 .replace(":3D", "=") 34 .replace(":40", "@"); 35 36 Some(res) 37} 38 39pub fn url_to_rkey(url: String) -> Option<String> { 40 let regex = Regex::new(r"^(?:[a-zA-Z0-9/\-._~!$&'()*+,;=:@]|(?:%[0-9a-fA-F]{2}))*$") 41 .expect("Regex failed to generate"); 42 if !regex.is_match(&url) { 43 return None; 44 } 45 46 let res = url 47 // : replace is hoisted so it doesnt replace colons from elsewhere 48 .replace(":", ":3A") 49 .replace("/", "::") 50 .replace("%", ":~") 51 .replace("!", ":21") 52 .replace("$", ":24") 53 .replace("&", ":26") 54 .replace("'", ":27") 55 .replace("(", ":28") 56 .replace(")", ":29") 57 .replace("*", ":2A") 58 .replace("+", ":2B") 59 .replace(",", ":2C") 60 .replace(";", ":3B") 61 .replace("=", ":3D") 62 .replace("@", ":40"); 63 64 Some(res) 65} 66 67pub fn site_handle(user: String) -> String { 68 if user.contains(":") { 69 let user = user.split(":").collect::<Vec<_>>(); 70 let method = user[1]; 71 let did = user[2]; 72 format!("https://{did}.did-{method}.atcities.dev/") 73 } else { 74 format!("https://{user}.atcities.dev/") 75 } 76}