The smokesignal.events web application

chore: removing facet-gen

-112
-112
src/bin/facet-gen.rs
··· 1 - //! Command-line tool for generating AT Protocol facet arrays from text. 2 - //! 3 - //! This tool parses a string and outputs the facet array in JSON format. 4 - //! Facets include mentions (@handle), URLs (https://...), and hashtags (#tag). 5 - //! 6 - //! Note: Mentions are detected but not resolved to DIDs (requires network access). 7 - //! The output includes placeholder DIDs for mentions that would need resolution. 8 - //! 9 - //! # Usage 10 - //! 11 - //! ```bash 12 - //! cargo run --bin facet-gen -- "Check out https://example.com and #rust" 13 - //! ``` 14 - 15 - use atproto_record::lexicon::app::bsky::richtext::facet::{ 16 - ByteSlice, Facet, FacetFeature, Link, Mention, Tag, 17 - }; 18 - use smokesignal::facets::{parse_mentions, parse_tags, parse_urls}; 19 - use std::env; 20 - 21 - fn main() { 22 - let args: Vec<String> = env::args().collect(); 23 - 24 - if args.len() != 2 { 25 - eprintln!("Usage: {} \"<text>\"", args[0]); 26 - eprintln!(); 27 - eprintln!("Example:"); 28 - eprintln!(" {} \"Check out https://example.com and @alice.bsky.social #rust\"", args[0]); 29 - std::process::exit(1); 30 - } 31 - 32 - let text = &args[1]; 33 - let mut facets: Vec<Facet> = Vec::new(); 34 - 35 - // Parse mentions (note: DIDs are placeholders since we can't resolve without network) 36 - let mention_spans = parse_mentions(text); 37 - for mention in mention_spans { 38 - facets.push(Facet { 39 - index: ByteSlice { 40 - byte_start: mention.start, 41 - byte_end: mention.end, 42 - }, 43 - features: vec![FacetFeature::Mention(Mention { 44 - did: format!("did:plc:<unresolved:{}>", mention.handle), 45 - })], 46 - }); 47 - } 48 - 49 - // Parse URLs 50 - let url_spans = parse_urls(text); 51 - for url in url_spans { 52 - facets.push(Facet { 53 - index: ByteSlice { 54 - byte_start: url.start, 55 - byte_end: url.end, 56 - }, 57 - features: vec![FacetFeature::Link(Link { uri: url.url })], 58 - }); 59 - } 60 - 61 - // Parse hashtags 62 - let tag_spans = parse_tags(text); 63 - for tag_span in tag_spans { 64 - facets.push(Facet { 65 - index: ByteSlice { 66 - byte_start: tag_span.start, 67 - byte_end: tag_span.end, 68 - }, 69 - features: vec![FacetFeature::Tag(Tag { tag: tag_span.tag })], 70 - }); 71 - } 72 - 73 - // Sort facets by byte_start for consistent output 74 - facets.sort_by_key(|f| f.index.byte_start); 75 - 76 - // Output as JSON 77 - if facets.is_empty() { 78 - println!("null"); 79 - } else { 80 - match serde_json::to_string_pretty(&facets) { 81 - Ok(json) => println!("{}", json), 82 - Err(e) => { 83 - eprintln!("Error serializing facets: {}", e); 84 - std::process::exit(1); 85 - } 86 - } 87 - } 88 - 89 - // Also print debug info to stderr 90 - eprintln!(); 91 - eprintln!("--- Debug Info ---"); 92 - eprintln!("Input text: {:?}", text); 93 - eprintln!("Text length: {} bytes", text.len()); 94 - eprintln!("Facets found: {}", facets.len()); 95 - 96 - // Show byte slice verification 97 - let text_bytes = text.as_bytes(); 98 - for (i, facet) in facets.iter().enumerate() { 99 - let start = facet.index.byte_start; 100 - let end = facet.index.byte_end; 101 - let slice_text = std::str::from_utf8(&text_bytes[start..end]).unwrap_or("<invalid utf8>"); 102 - let feature_type = match &facet.features[0] { 103 - FacetFeature::Mention(_) => "mention", 104 - FacetFeature::Link(_) => "link", 105 - FacetFeature::Tag(_) => "tag", 106 - }; 107 - eprintln!( 108 - " [{}] {} @ bytes {}..{}: {:?}", 109 - i, feature_type, start, end, slice_text 110 - ); 111 - } 112 - }