Skip to content

hey-jj/structtag

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

structtag

Parse and modify Go struct field tag literals.

A Go struct field tag is one string of space-separated key:"value" pairs, for example:

json:"foo,omitempty,string" xml:"foo"

Each quoted value is a comma-separated list. The first element is the name, the rest are options. So json:"foo,omitempty" has key json, name foo, and one option omitempty.

This crate parses such a string into an ordered collection, lets you read and edit the pairs, and reassembles them into canonical key:"value" literals.

Install

[dependencies]
structtag = "0.1"

Example

use structtag::{parse, Tag};

let mut tags = parse(r#"json:"foo,omitempty,string" xml:"foo""#).unwrap();

// Read a tag.
let json = tags.get("json").unwrap();
assert_eq!(json.name, "foo");
assert_eq!(json.options.as_slice(), &["omitempty".to_string(), "string".to_string()]);

// Rename it, drop its options, write it back.
let mut json = json;
json.name = "foo_bar".to_string();
json.options.clear();
tags.set(json).unwrap();

// Add a tag.
tags.set(Tag::new("hcl", "foo", ["squash"])).unwrap();
assert_eq!(tags.to_string(), r#"json:"foo_bar" xml:"foo" hcl:"foo,squash""#);

// Sort by key.
tags.sort();
assert_eq!(tags.to_string(), r#"hcl:"foo,squash" json:"foo_bar" xml:"foo""#);

API

parse(tag: &str) -> Result<Tags, StructTagError> turns a raw tag string into a [Tags] collection. An empty input and an input of only spaces both give an empty collection. A malformed pair gives Err.

Tags keeps pairs in parse order and offers get, set, add_options, delete_options, delete, tags, keys, len, sort, and Display. get returns a copy of the stored tag. Edit the copy and write it back with set.

Tag holds key, name, and options, with has_option and value. Its Display re-quotes the value the way Go's %q verb does, so the render is canonical. A tag whose input was already canonical round-trips byte-for-byte. Other inputs reconstruct the same value, not the same bytes. Options::is_nil reports whether the option list is nil or an explicit empty list, and Debug prints nil for the nil form.

Behavior notes

  • Scanning is byte-based. The byte 0x7f ends a key. Multi-byte control runes are not special.
  • The option list distinguishes "no options" from "an explicit empty list". Both render the same through value and Display. Options::is_nil reports the difference, and the Debug view prints nil for the first form.
  • A lone empty option is dropped on render. A value of foo, yields name foo and renders as foo.
  • Tag values are treated as UTF-8. A byte escape that would produce invalid UTF-8 (for example \377 standing alone) is rejected as a value syntax error rather than producing a non-UTF-8 byte string.

License

Licensed under the MIT license.

About

parse and modify Go struct field tag literals

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages