allow more flexibility in specifying options

Options can be specified in any order (size no longer needs to be listed
first), and may be repeated.  Duplicated options overwrite previous
values.  Technically, non-size options could already be repeated... now
size can as well.  There's really not much value to this, it's just an
side-effect of allowing any order.

fixes #5
This commit is contained in:
Will Norris 2013-12-26 13:35:23 -08:00
parent b4ed3507e3
commit 0a939cc19d
3 changed files with 47 additions and 27 deletions

View file

@ -61,27 +61,9 @@ func (o Options) String() string {
func ParseOptions(str string) *Options { func ParseOptions(str string) *Options {
o := new(Options) o := new(Options)
var h, w string
parts := strings.Split(str, ",") parts := strings.Split(str, ",")
for _, part := range parts {
// parse size
size := strings.SplitN(parts[0], "x", 2)
w = size[0]
if len(size) > 1 {
h = size[1]
} else {
h = w
}
if w != "" {
o.Width, _ = strconv.ParseFloat(w, 64)
}
if h != "" {
o.Height, _ = strconv.ParseFloat(h, 64)
}
for _, part := range parts[1:] {
if part == "fit" { if part == "fit" {
o.Fit = true o.Fit = true
continue continue
@ -95,10 +77,35 @@ func ParseOptions(str string) *Options {
continue continue
} }
if len(part) > 2 && strings.HasPrefix(part, "r") { if len(part) > 2 && part[:1] == "r" {
o.Rotate, _ = strconv.Atoi(part[1:]) o.Rotate, _ = strconv.Atoi(part[1:])
continue continue
} }
if strings.ContainsRune(part, 'x') {
var h, w string
size := strings.SplitN(part, "x", 2)
w = size[0]
if len(size) > 1 {
h = size[1]
} else {
h = w
}
if w != "" {
o.Width, _ = strconv.ParseFloat(w, 64)
}
if h != "" {
o.Height, _ = strconv.ParseFloat(h, 64)
}
continue
}
if size, err := strconv.ParseFloat(part, 64); err == nil {
o.Width = size
o.Height = size
continue
}
} }
return o return o

View file

@ -46,6 +46,7 @@ func TestParseOptions(t *testing.T) {
{"", emptyOptions}, {"", emptyOptions},
{"x", emptyOptions}, {"x", emptyOptions},
{"0", emptyOptions}, {"0", emptyOptions},
{",,,,", emptyOptions},
// size variations // size variations
{"1x", &Options{Width: 1}}, {"1x", &Options{Width: 1}},
@ -54,12 +55,23 @@ func TestParseOptions(t *testing.T) {
{"0.1x0.2", &Options{Width: 0.1, Height: 0.2}}, {"0.1x0.2", &Options{Width: 0.1, Height: 0.2}},
// additional flags // additional flags
{",fit", &Options{Fit: true}}, {"fit", &Options{Fit: true}},
{",r90", &Options{Rotate: 90}}, {"r90", &Options{Rotate: 90}},
{",fv", &Options{FlipVertical: true}}, {"fv", &Options{FlipVertical: true}},
{",fh", &Options{FlipHorizontal: true}}, {"fh", &Options{FlipHorizontal: true}},
// duplicate flags (last one wins)
{"1x2,3x4", &Options{Width: 3, Height: 4}},
{"1x2,3", &Options{Width: 3, Height: 3}},
{"1x2,0x3", &Options{Width: 0, Height: 3}},
{"1x,x2", &Options{Width: 1, Height: 2}},
{"r90,r270", &Options{Rotate: 270}},
// mix of valid and invalid flags
{"FOO,1,BAR,r90,BAZ", &Options{Width: 1, Height: 1, Rotate: 90}},
{"1x2,fit,r90,fv,fh", &Options{1, 2, true, 90, true, true}}, {"1x2,fit,r90,fv,fh", &Options{1, 2, true, 90, true, true}},
{"r90,fh,1x2,fv,fit", &Options{1, 2, true, 90, true, true}},
} }
for i, tt := range tests { for i, tt := range tests {

View file

@ -24,9 +24,10 @@ imageproxy URLs are of the form `http://localhost/{options}/{remote_url}`.
### Options ### ### Options ###
Options are specified as a comma delimited list of parameters, the first of Options are specified as a comma delimited list of parameters, which can be
which always specifies image size. The format is a superset of [resize.ly's supplied in any order. Duplicate parameters overwrite previous values.
options](https://resize.ly/#demo).
The format is a superset of [resize.ly's options](https://resize.ly/#demo).
#### Size #### #### Size ####