mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Adds @uri/@urid #1529
This commit is contained in:
parent
dd6cf3df14
commit
6d7d76a3f1
@ -15,6 +15,7 @@ const (
|
||||
JsonInputFormat
|
||||
CSVObjectInputFormat
|
||||
TSVObjectInputFormat
|
||||
UriInputFormat
|
||||
)
|
||||
|
||||
type Decoder interface {
|
||||
|
60
pkg/yqlib/decoder_uri.go
Normal file
60
pkg/yqlib/decoder_uri.go
Normal file
@ -0,0 +1,60 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type uriDecoder struct {
|
||||
reader io.Reader
|
||||
finished bool
|
||||
readAnything bool
|
||||
}
|
||||
|
||||
func NewUriDecoder() Decoder {
|
||||
return &uriDecoder{finished: false}
|
||||
}
|
||||
|
||||
func (dec *uriDecoder) Init(reader io.Reader) error {
|
||||
dec.reader = reader
|
||||
dec.readAnything = false
|
||||
dec.finished = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dec *uriDecoder) Decode() (*CandidateNode, error) {
|
||||
if dec.finished {
|
||||
return nil, io.EOF
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
if _, err := buf.ReadFrom(dec.reader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf.Len() == 0 {
|
||||
dec.finished = true
|
||||
|
||||
// if we've read _only_ an empty string, lets return that
|
||||
// otherwise if we've already read some bytes, and now we get
|
||||
// an empty string, then we are done.
|
||||
if dec.readAnything {
|
||||
return nil, io.EOF
|
||||
}
|
||||
}
|
||||
newValue, err := url.QueryUnescape(buf.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dec.readAnything = true
|
||||
return &CandidateNode{
|
||||
Node: &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!str",
|
||||
Value: newValue,
|
||||
},
|
||||
}, nil
|
||||
}
|
@ -16,6 +16,7 @@ These operators are useful to process yaml documents that have stringified embed
|
||||
| TSV | from_tsv/@tsvd | to_tsv/@tsv |
|
||||
| XML | from_xml/@xmld | to_xml(i)/@xml |
|
||||
| Base64 | @base64d | @base64 |
|
||||
| URI | @urid | @uri |
|
||||
|
||||
|
||||
See CSV and TSV [documentation](https://mikefarah.gitbook.io/yq/usage/csv-tsv) for accepted formats.
|
||||
@ -435,6 +436,34 @@ will output
|
||||
YTogYXBwbGUK
|
||||
```
|
||||
|
||||
## Encode a string to uri
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
coolData: this has & special () characters *
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '.coolData | @uri' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
this+has+%26+special+%28%29+characters+%2A
|
||||
```
|
||||
|
||||
## Decode a URI to a string
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
this+has+%26+special+%28%29+characters+%2A
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq '@urid' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
this has & special () characters *
|
||||
```
|
||||
|
||||
## Decode a base64 encoded string
|
||||
Decoded data is assumed to be a string.
|
||||
|
||||
|
@ -16,6 +16,7 @@ These operators are useful to process yaml documents that have stringified embed
|
||||
| TSV | from_tsv/@tsvd | to_tsv/@tsv |
|
||||
| XML | from_xml/@xmld | to_xml(i)/@xml |
|
||||
| Base64 | @base64d | @base64 |
|
||||
| URI | @urid | @uri |
|
||||
|
||||
|
||||
See CSV and TSV [documentation](https://mikefarah.gitbook.io/yq/usage/csv-tsv) for accepted formats.
|
||||
|
37
pkg/yqlib/encoder_uri.go
Normal file
37
pkg/yqlib/encoder_uri.go
Normal file
@ -0,0 +1,37 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type uriEncoder struct {
|
||||
}
|
||||
|
||||
func NewUriEncoder() Encoder {
|
||||
return &uriEncoder{}
|
||||
}
|
||||
|
||||
func (e *uriEncoder) CanHandleAliases() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *uriEncoder) PrintDocumentSeparator(writer io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *uriEncoder) PrintLeadingContent(writer io.Writer, content string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *uriEncoder) Encode(writer io.Writer, originalNode *yaml.Node) error {
|
||||
node := unwrapDoc(originalNode)
|
||||
if guessTagFromCustomType(node) != "!!str" {
|
||||
return fmt.Errorf("cannot encode %v as url, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
|
||||
}
|
||||
_, err := writer.Write([]byte(url.QueryEscape(originalNode.Value)))
|
||||
return err
|
||||
}
|
@ -78,6 +78,9 @@ var participleYqRules = []*participleYqRule{
|
||||
{"Base64d", `@base64d`, decodeOp(Base64InputFormat), 0},
|
||||
{"Base64", `@base64`, encodeWithIndent(Base64OutputFormat, 0), 0},
|
||||
|
||||
{"Urld", `@urid`, decodeOp(UriInputFormat), 0},
|
||||
{"Url", `@uri`, encodeWithIndent(UriOutputFormat, 0), 0},
|
||||
|
||||
{"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(ConfiguredXMLPreferences), false), 0},
|
||||
|
||||
{"LoadBase64", `load_?base64`, loadOp(NewBase64Decoder(), false), 0},
|
||||
|
@ -26,6 +26,8 @@ func configureEncoder(format PrinterOutputFormat, indent int) Encoder {
|
||||
return NewXMLEncoder(indent, ConfiguredXMLPreferences)
|
||||
case Base64OutputFormat:
|
||||
return NewBase64Encoder()
|
||||
case UriOutputFormat:
|
||||
return NewUriEncoder()
|
||||
}
|
||||
panic("invalid encoder")
|
||||
}
|
||||
@ -113,6 +115,8 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
||||
decoder = NewCSVObjectDecoder(',')
|
||||
case TSVObjectInputFormat:
|
||||
decoder = NewCSVObjectDecoder('\t')
|
||||
case UriInputFormat:
|
||||
decoder = NewUriDecoder()
|
||||
}
|
||||
|
||||
var results = list.New()
|
||||
|
@ -241,6 +241,22 @@ var encoderDecoderOperatorScenarios = []expressionScenario{
|
||||
"D0, P[], (!!str)::YTogYXBwbGUK\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Encode a string to uri",
|
||||
document: "coolData: this has & special () characters *",
|
||||
expression: ".coolData | @uri",
|
||||
expected: []string{
|
||||
"D0, P[coolData], (!!str)::this+has+%26+special+%28%29+characters+%2A\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Decode a URI to a string",
|
||||
document: "this+has+%26+special+%28%29+characters+%2A",
|
||||
expression: "@urid",
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::this has & special () characters *\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Decode a base64 encoded string",
|
||||
subdescription: "Decoded data is assumed to be a string.",
|
||||
|
@ -27,6 +27,7 @@ const (
|
||||
TSVOutputFormat
|
||||
XMLOutputFormat
|
||||
Base64OutputFormat
|
||||
UriOutputFormat
|
||||
)
|
||||
|
||||
func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user