review

review patchsets using your default editor
Log | Files | Refs

txt.odin (1557B)


      1 /*
      2 Package txt is the few readings of plain text that several packages
      3 share: the words a name is made of, a plural made singular, and the JSON
      4 object inside an answer.
      5 */
      6 package txt
      7 
      8 import "core:strings"
      9 
     10 // split_words breaks a name into the words it is made of: a capital
     11 // starts a word, an underscore ends one, as snake_case languages put the
     12 // next word after it.
     13 split_words :: proc(name: string, allocator := context.allocator) -> []string {
     14 	words := make([dynamic]string, allocator)
     15 	start := 0
     16 	for i in 0 ..< len(name) {
     17 		c := name[i]
     18 		if i > 0 && ((c >= 'A' && c <= 'Z') || c == '_') {
     19 			if i > start {
     20 				append(&words, name[start:i])
     21 			}
     22 			start = i + 1 if c == '_' else i
     23 		}
     24 	}
     25 	if start < len(name) {
     26 		append(&words, name[start:])
     27 	}
     28 	return words[:]
     29 }
     30 
     31 // depluralise drops a trailing s, except where dropping it would leave
     32 // another: class stays class.
     33 depluralise :: proc(w: string) -> string {
     34 	if len(w) > 3 && strings.has_suffix(w, "s") && w[len(w) - 2] != 's' {
     35 		return w[:len(w) - 1]
     36 	}
     37 	return w
     38 }
     39 
     40 // object finds the JSON object in a text that has prose around it: from
     41 // the first brace to the last. Only a provider that can enforce a schema
     42 // returns bare JSON; the rest wrap it in whatever they were minded to
     43 // say, and a compiler prints its own prose before its JSON when it cannot
     44 // even start.
     45 object :: proc(s: string) -> (string, bool) {
     46 	start := strings.index_byte(s, '{')
     47 	end := strings.last_index_byte(s, '}')
     48 	if start < 0 || end < start {
     49 		return "", false
     50 	}
     51 	return s[start:end + 1], true
     52 }