Add support for percent offset

This commit is contained in:
Olivier Poitrey 2015-09-23 10:08:59 -07:00
Родитель 6ed8256f43
Коммит 07a231a892
4 изменённых файлов: 87 добавлений и 4 удалений

Просмотреть файл

@ -30,7 +30,7 @@ func TestDurationMarshaler(t *testing.T) {
}
}
func TestDurationUnmarshalXML(t *testing.T) {
func TestDurationUnmarshal(t *testing.T) {
var d Duration
if assert.NoError(t, d.UnmarshalText([]byte("00:00:00"))) {
assert.Equal(t, Duration(0), d)

38
offset.go Normal file
Просмотреть файл

@ -0,0 +1,38 @@
package vast
import (
"fmt"
"strconv"
"strings"
)
// Offset represents either a vast.Duration or a percentage of the video duration.
type Offset struct {
// If not nil, the Offset is duration based
Duration *Duration
// If Duration is nil, the Offset is percent based
Percent float32
}
// MarshalText implements the encoding.TextMarshaler interface.
func (o Offset) MarshalText() ([]byte, error) {
if o.Duration != nil {
return o.Duration.MarshalText()
}
return []byte(fmt.Sprintf("%d%%", int(o.Percent*100))), nil
}
// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (o *Offset) UnmarshalText(data []byte) error {
if strings.HasSuffix(string(data), "%") {
p, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 8)
if err != nil {
return fmt.Errorf("invalid offset: %s", data)
}
o.Percent = float32(p) / 100
return nil
}
var d Duration
o.Duration = &d
return o.Duration.UnmarshalText(data)
}

45
offset_test.go Normal file
Просмотреть файл

@ -0,0 +1,45 @@
package vast
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestOffsetMarshaler(t *testing.T) {
b, err := Offset{}.MarshalText()
if assert.NoError(t, err) {
assert.Equal(t, "0%", string(b))
}
b, err = Offset{Percent: .1}.MarshalText()
if assert.NoError(t, err) {
assert.Equal(t, "10%", string(b))
}
d := Duration(0)
b, err = Offset{Duration: &d}.MarshalText()
if assert.NoError(t, err) {
assert.Equal(t, "00:00:00", string(b))
}
}
func TestOffsetUnmarshaler(t *testing.T) {
var o Offset
if assert.NoError(t, o.UnmarshalText([]byte("0%"))) {
assert.Nil(t, o.Duration)
assert.Equal(t, float32(0.0), o.Percent)
}
o = Offset{}
if assert.NoError(t, o.UnmarshalText([]byte("10%"))) {
assert.Nil(t, o.Duration)
assert.Equal(t, float32(0.1), o.Percent)
}
o = Offset{}
if assert.NoError(t, o.UnmarshalText([]byte("00:00:00"))) {
if assert.NotNil(t, o.Duration) {
assert.Equal(t, Duration(0), *o.Duration)
}
assert.Equal(t, float32(0), o.Percent)
}
o = Offset{}
assert.EqualError(t, o.UnmarshalText([]byte("abc%")), "invalid offset: abc%")
}

Просмотреть файл

@ -210,7 +210,7 @@ type Linear struct {
// represents milliseconds and is optional. This skipoffset value
// indicates when the skip control should be provided after the creative
// begins playing.
SkipOffset Duration `xml:"skipoffset,attr,omitempty"`
SkipOffset Offset `xml:"skipoffset,attr,omitempty"`
// Duration in standard time format, hh:mm:ss
Duration Duration
AdParameters *AdParameters `xml:",omitempty"`
@ -389,7 +389,7 @@ type Icon struct {
// Must match ([0-9]*|top|bottom)
YPosition string `xml:"xPosition,attr"`
// Start time at which the player should display the icon. Expressed in standard time format hh:mm:ss.
Offset Duration `xml:"offset,attr"`
Offset Offset `xml:"offset,attr"`
// duration for which the player must display the icon. Expressed in standard time format hh:mm:ss.
Duration Duration `xml:"duration,attr"`
// The apiFramework defines the method to use for communication with the icon element
@ -417,7 +417,7 @@ type Tracking struct {
Event string `xml:"event,attr"`
// The time during the video at which this url should be pinged. Must be present for
// progress event. Must match (\d{2}:[0-5]\d:[0-5]\d(\.\d\d\d)?|1?\d?\d(\.?\d)*%)
Offset string `xml:"offset,attr,omitempty"`
Offset Offset `xml:"offset,attr,omitempty"`
URI string `xml:",chardata"`
}