pub fn find_knot(did: &String, repo_name: &String, pds: &String) -> Result { // https://docs.bsky.app/docs/api/com-atproto-repo-list-records let mut cursor: Option = None; loop { let url = format!( "{0}/xrpc/com.atproto.repo.listRecords?collection=sh.tangled.repo&repo={1}&cursor={2}", pds.clone(), did.clone(), cursor.clone().unwrap_or(String::new()) ); let res = match reqwest::blocking::get(url) { Ok(val) => val, Err(_) => { println!(" Failed to load repos."); return Err(()); } }; if !res.status().is_success() { println!(" Got non 2xx code when loading repos"); return Err(()); } let body = match res.text() { Ok(val) => match json::parse(&val) { Ok(val) => val, Err(_) => { println!(" Invalid or malformed response response"); return Err(()); } }, Err(_) => { println!(" Missing body from response"); return Err(()); } }; // must contain a records array if !body["records"].is_array() { println!(" Invalid or malformed response response"); return Err(()); } for record in body["records"].members() { if let Some(val) = record["value"]["name"].as_str() && val == repo_name { if let Some(knot) = record["value"]["knot"].as_str() { return Ok(String::from(knot)); } else { println!(" Repo didn't have a valid knot"); return Err(()); } } } if let Some(val) = body["cursor"].as_str() { cursor = Some(String::from(val)) } else { break; } } return Err(()); }