From 848481fd1a738225664fa398275fcd1afd61c4ff Mon Sep 17 00:00:00 2001 From: demo Date: Thu, 28 May 2026 17:28:59 -0400 Subject: feat: implement shortcode feature --- shortcodes.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 shortcodes.go (limited to 'shortcodes.go') diff --git a/shortcodes.go b/shortcodes.go new file mode 100644 index 0000000..978b39b --- /dev/null +++ b/shortcodes.go @@ -0,0 +1,50 @@ +package main + +import ( + "encoding/csv" + "fmt" + "io" + "os" +) + +// getURLFromShortcode looks for the shortcode inside the file +// specified by filename (default "urls.csv" in the top-level project +// directory), and returns the associated URL. +// +// Right now we perform an O(n) search across the entire file just to +// get a single URL, so there's room for improvement here. +func getURLFromShortcode(filename, shortcode string) (string, error) { + f, err := os.Open(filename) + if err != nil { + return "", fmt.Errorf("can't open shortcode file: %w", err) + } + defer f.Close() + + r := csv.NewReader(f) + + // Read, vet, and discard the column-header row. + header, err := r.Read() + if err != nil { + return "", fmt.Errorf("missing header line: %w", err) + } + + if header[0] != "shortcode" || header[1] != "url" { + return "", fmt.Errorf("invalid CSV header: %v", header) + } + + for i := 1; ; i++ { + record, err := r.Read() + if err == io.EOF { + break + } + if err != nil { + return "", fmt.Errorf("error reading %s, row %d: %w", filename, i, err) + } + + if record[0] == shortcode { + return record[1], nil + } + } + + return "", fmt.Errorf("no URL with shortcode %s", shortcode) +} -- cgit v1.2.3