diff --git a/fetch_embed.go b/fetch_embed.go
new file mode 100644
index 0000000..c4a6e88
--- /dev/null
+++ b/fetch_embed.go
@@ -0,0 +1,53 @@
+package oembed
+
+import (
+ "strconv"
+
+ json "github.com/pquerna/ffjson/ffjson"
+ http "github.com/valyala/fasthttp"
+ template "github.com/valyala/fasttemplate"
+)
+
+type Params struct {
+ MaxWidth int
+ MaxHeight int
+}
+
+func fetchEmbed(url string, provider providerCandidate, params *Params) (*Response, error) {
+ resourceUrl := provider.URL
+ resourceUrl = template.ExecuteString(resourceUrl, "{", "}", map[string]interface{}{"format": "json"})
+
+ link := http.AcquireURI()
+ defer http.ReleaseURI(link)
+ link.Update(resourceUrl)
+ qa := link.QueryArgs()
+ qa.Add("format", "json")
+ qa.Add("url", url)
+
+ if params != nil && params.MaxWidth != 0 {
+ qa.Add("maxwidth", strconv.Itoa(params.MaxWidth))
+ }
+ if params != nil && params.MaxHeight != 0 {
+ qa.Add("maxheight", strconv.Itoa(params.MaxHeight))
+ }
+ link.SetQueryStringBytes(qa.QueryString())
+
+ req := http.AcquireRequest()
+ defer http.ReleaseRequest(req)
+ req.SetRequestURIBytes(link.FullURI())
+
+ resp := http.AcquireResponse()
+ defer http.ReleaseResponse(resp)
+
+ if err := http.Do(req, resp); err != nil {
+ return nil, err
+ }
+
+ var response Response
+ if err := json.Unmarshal(resp.Body(), &response); err != nil {
+ return nil, err
+ }
+ response.ProviderName = provider.ProviderName
+ response.ProviderURL = provider.ProviderURL
+ return &response, nil
+}
diff --git a/fetch_embed_test.go b/fetch_embed_test.go
new file mode 100644
index 0000000..7d51a8a
--- /dev/null
+++ b/fetch_embed_test.go
@@ -0,0 +1,58 @@
+package oembed
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestFetchEmbed(t *testing.T) {
+ assert := assert.New(t)
+ t.Run("valid", func(t *testing.T) {
+ resp, err := fetchEmbed(
+ "https://www.youtube.com/watch?v=8jPQjjsBbIc",
+ makeCandidate(Provider{
+ Name: "YouTube",
+ URL: "https://www.youtube.com/",
+ Endpoints: []Endpoint{Endpoint{
+ Schemes: []string{
+ "https://*.youtube.com/watch*",
+ "https://*.youtube.com/v/*\"",
+ "https://youtu.be/*",
+ },
+ URL: "https://www.youtube.com/oembed",
+ Discovery: true,
+ }},
+ }),
+ &Params{
+ MaxWidth: 250,
+ MaxHeight: 250,
+ },
+ )
+ assert.NoError(err)
+ assert.NotNil(resp)
+ })
+ t.Run("invalid", func(t *testing.T) {
+ for _, url := range []string{
+ "",
+ "htt:/abc.com/failed-none-sense",
+ "https://abc.com/failed-none-sense",
+ "http://badcom/146753785",
+ "https://674458092126388225",
+ "http://www.ted.com/talks/something-does-not-exist",
+ "https://soundcloud^(*%%$%^$$%$$*&(&)())",
+ "https://www.flickr.com/services/oembed/?url=http%3A//www.flickr.com/photos/bees/23416sa/",
+ } {
+ url := url
+ t.Run(url, func(t *testing.T) {
+ c := findProvider(url)
+ if c == nil {
+ c = new(providerCandidate)
+ }
+
+ _, err := fetchEmbed(url, *c, nil)
+ assert.Error(err)
+ })
+ }
+ })
+}
diff --git a/find_provider.go b/find_provider.go
new file mode 100644
index 0000000..fdec3c4
--- /dev/null
+++ b/find_provider.go
@@ -0,0 +1,74 @@
+package oembed
+
+import (
+ "regexp"
+ "strings"
+
+ http "github.com/valyala/fasthttp"
+)
+
+type providerCandidate struct {
+ Domain string
+ ProviderName string
+ ProviderURL string
+ Schemes []string
+ URL string
+}
+
+func getHostname(url string) string {
+ u := http.AcquireURI()
+ defer http.ReleaseURI(u)
+ u.Update(url)
+ if u.Host() != nil {
+ return strings.TrimPrefix(string(u.Host()), "www.")
+ }
+ return ""
+}
+
+func makeCandidate(p Provider) providerCandidate {
+ endpoint := p.Endpoints[0]
+ domain := getHostname(endpoint.URL)
+ if domain != "" {
+ domain = strings.TrimPrefix(domain, "www.")
+ } else {
+ domain = ""
+ }
+
+ return providerCandidate{
+ ProviderName: p.Name,
+ ProviderURL: p.URL,
+ Schemes: endpoint.Schemes,
+ URL: endpoint.URL,
+ Domain: domain,
+ }
+
+}
+
+func findProvider(url string) *providerCandidate {
+ var candidates []providerCandidate
+ for _, provider := range providersList {
+ provider := provider
+ candidate := makeCandidate(provider)
+ if len(candidate.Schemes) == 0 {
+ if !strings.Contains(url, candidate.Domain) {
+ continue
+ }
+ candidates = append(candidates, candidate)
+ continue
+ }
+ for _, scheme := range candidate.Schemes {
+ scheme := scheme
+ reg := regexp.MustCompile(strings.Replace(scheme, "*", "(.*)", -1))
+ if !reg.MatchString(url) {
+ continue
+ }
+
+ candidates = append(candidates, candidate)
+ break
+ }
+ }
+ if len(candidates) == 0 {
+ return nil
+ }
+ return &candidates[0]
+}
diff --git a/find_provider_test.go b/find_provider_test.go
new file mode 100644
index 0000000..691c273
--- /dev/null
+++ b/find_provider_test.go
@@ -0,0 +1,44 @@
+package oembed
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGetHostname(t *testing.T) {
+ assert := assert.New(t)
+ for k, v := range map[string]string{
+ "https://mais.uol.com.br/": "mais.uol.com.br",
+ "http://www.wootled.com/": "wootled.com",
+ "http://yfrog.com": "yfrog.com",
+ "https://www.youtube.com": "youtube.com",
+ "https://www.znipe.tv": "znipe.tv",
+ "http://": "",
+ "": "",
+ } {
+ t.Run(k, func(t *testing.T) { assert.Equal(v, getHostname(k)) })
+ }
+}
+
+func TestMakeCandidate(t *testing.T) {
+ assert.NotNil(t, makeCandidate(Provider{
+ Name: "YouTube",
+ URL: "https://www.youtube.com/",
+ Endpoints: []Endpoint{
+ Endpoint{
+ Schemes: []string{
+ "https://*.youtube.com/watch*",
+ "https://*.youtube.com/v/*\"",
+ "https://youtu.be/*",
+ },
+ URL: "https://www.youtube.com/oembed",
+ Discovery: true,
+ },
+ },
+ }))
+}
+
+func TestFindProvider(t *testing.T) {
+ assert.NotNil(t, findProvider("https://www.beautiful.ai/"))
+}
diff --git a/is_valid_url.go b/is_valid_url.go
new file mode 100644
index 0000000..902ea47
--- /dev/null
+++ b/is_valid_url.go
@@ -0,0 +1,8 @@
+package oembed
+
+import "net/url"
+
+func isValidURL(src string) bool {
+ _, err := url.ParseRequestURI(src)
+ return err == nil
+}
diff --git a/is_valid_url_test.go b/is_valid_url_test.go
new file mode 100644
index 0000000..d6e456a
--- /dev/null
+++ b/is_valid_url_test.go
@@ -0,0 +1,17 @@
+package oembed
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func Test_IsValidURL(t *testing.T) {
+ assert := assert.New(t)
+ t.Run("invalid", func(t *testing.T) {
+ assert.False(isValidURL("str"))
+ })
+ t.Run("valid", func(t *testing.T) {
+ assert.True(isValidURL("http://www.kickstarter.com"))
+ })
+}
diff --git a/oembed.go b/oembed.go
new file mode 100644
index 0000000..f8dd3c5
--- /dev/null
+++ b/oembed.go
@@ -0,0 +1,24 @@
+package oembed
+
+import (
+ "golang.org/x/xerrors"
+)
+
+var (
+ ErrInvalidInputURL = xerrors.New("invalid input url")
+ ErrNoProviderFound = xerrors.New("no provider found with given url")
+)
+
+func Extract(url string, params *Params) (*Response, error) {
+ if !isValidURL(url) {
+ return nil, ErrInvalidInputURL
+ }
+ if c := findProvider(url); c != nil {
+ return fetchEmbed(url, *c, params)
+ }
+ return nil, ErrNoProviderFound
+}
+
+func HasProvider(url string) bool {
+ return findProvider(url) != nil
+}
diff --git a/oembed_test.go b/oembed_test.go
new file mode 100644
index 0000000..6172d2d
--- /dev/null
+++ b/oembed_test.go
@@ -0,0 +1,46 @@
+package oembed
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestExtract(t *testing.T) {
+ assert := assert.New(t)
+ t.Run("valid", func(t *testing.T) {
+ resp, err := Extract("https://www.youtube.com/watch?v=8jPQjjsBbIc", &Params{
+ MaxWidth: 250,
+ MaxHeight: 250,
+ })
+ assert.NoError(err)
+ assert.NotNil(resp)
+ })
+ t.Run("invalid", func(t *testing.T) {
+ for _, url := range []string{
+ "",
+ "htt:/abc.com/failed-none-sense",
+ "https://abc.com/failed-none-sense",
+ "http://badcom/146753785",
+ "https://674458092126388225",
+ "http://www.ted.com/talks/something-does-not-exist",
+ "https://soundcloud^(*%%$%^$$%$$*&(&)())",
+ "https://www.flickr.com/services/oembed/?url=http%3A//www.flickr.com/photos/bees/23416sa/",
+ } {
+ url := url
+ t.Run(url, func(t *testing.T) {
+ _, err := Extract(url, nil)
+ assert.Error(err)
+ })
+ }
+ })
+}
+
+func TestHasProvider(t *testing.T) {
+ t.Run("true", func(t *testing.T) {
+ assert.True(t, HasProvider("https://www.youtube.com/watch?v=8jPQjjsBbIc"))
+ })
+ t.Run("false", func(t *testing.T) {
+ assert.False(t, HasProvider("https://blog.toby3d.me/"))
+ })
+}
diff --git a/sync.go b/sync.go
new file mode 100644
index 0000000..7d0ba2d
--- /dev/null
+++ b/sync.go
@@ -0,0 +1,49 @@
+package oembed
+
+import (
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+
+ json "github.com/pquerna/ffjson/ffjson"
+ http "github.com/valyala/fasthttp"
+)
+
+const source string = "https://oembed.com/providers.json"
+
+var (
+ providersList []Provider
+
+ target = filepath.Join(
+ os.Getenv("GOPATH"), "src", "gitlab.com", "toby3d", "oembed", "assets", "providers.json",
+ )
+)
+
+func init() {
+ if err := fetch(source, target); err != nil {
+ panic(err)
+ }
+}
+
+func fetch(url, target string) error {
+ status, src, err := http.Get(nil, url)
+ if err != nil || status != http.StatusOK {
+ if src, err = ioutil.ReadFile(target); err != nil {
+ return err
+ }
+ }
+
+ if err := json.Unmarshal(src, &providersList); err != nil {
+ return err
+ }
+
+ if status == http.StatusOK {
+ if err = ioutil.WriteFile(target, src, os.ModePerm); err != nil {
+ return err
+ }
+ }
+
+ log.Println("providers.json has been updated")
+ return nil
+}
diff --git a/types.go b/types.go
new file mode 100644
index 0000000..0c7841d
--- /dev/null
+++ b/types.go
@@ -0,0 +1,106 @@
+//go:generate ffjson $GOFILE
+package oembed
+
+type (
+ Provider struct {
+ Name string `json:"provider_name"`
+ URL string `json:"provider_url"`
+ Endpoints []Endpoint `json:"endpoints"`
+ }
+
+ Endpoint struct {
+ Schemes []string `json:"schemes,omitempty"`
+ URL string `json:"url"`
+ Discovery bool `json:"discovery,omitempty"`
+ Formats []string `json:"formats,omitempty"`
+ }
+
+ // Response can specify a resource type, such as photo or video.
+ // Each type has specific parameters associated with it.
+ Response struct {
+ // The resource type.
+ Type string `json:"type"` // required
+
+ // The oEmbed version number.
+ Version string `json:"version"` // required
+
+ // A text title, describing the resource.
+ Title string `json:"title,omitempty"`
+
+ // The name of the author/owner of the resource.
+ AuthorName string `json:"author_name,omitempty"`
+
+ // A URL for the author/owner of the resource.
+ AuthorURL string `json:"author_url,omitempty"`
+
+ // The name of the resource provider.
+ ProviderName string `json:"provider_name,omitempty"`
+
+ // The url of the resource provider.
+ ProviderURL string `json:"provider_url,omitempty"`
+
+ // The suggested cache lifetime for this resource, in seconds.
+ // Consumers may choose to use this value or not.
+ CacheAge int `json:"cache_age,omitempty"`
+
+ // A URL to a thumbnail image representing the resource.
+ // The thumbnail must respect any maxwidth and maxheight parameters.
+ // If this parameter is present, thumbnail_width and thumbnail_height must also be present.
+ ThumbnailURL string `json:"thumbnail_url,omitempty"`
+
+ // The width of the optional thumbnail.
+ // If this parameter is present, thumbnail_url and thumbnail_height must also be present.
+ ThumbnailWidth int `json:"thumbnail_width,omitempty"`
+
+ // The height of the optional thumbnail.
+ // If this parameter is present, thumbnail_url and thumbnail_width must also be present.
+ ThumbnailHeight int `json:"thumbnail_height,omitempty"`
+
+ URL string `json:"url,omitempty"`
+ }
+
+ // Photo is used for representing static photos.
+ Photo struct {
+ // The source URL of the image. Consumers should be able to insert this URL into an element.
+ // Only HTTP and HTTPS URLs are valid.
+ URL string `json:"url"` // required
+
+ // The width in pixels of the image specified in the url parameter.
+ Width int `json:"width"` // required
+
+ // The height in pixels of the image specified in the url parameter.
+ Height int `json:"height"` // required
+ }
+
+ // Video is used for representing playable videos.
+ Video struct {
+ // The HTML required to embed a video player. The HTML should have no padding or margins.
+ // Consumers may wish to load the HTML in an off-domain iframe to avoid XSS vulnerabilities.
+ HTML string `json:"html"` // required
+
+ // The width in pixels required to display the HTML.
+ Width int `json:"width"` // required
+
+ // The height in pixels required to display the HTML.
+ Height int `json:"height"` // required
+ }
+
+ // Link type allow a provider to return any generic embed data (such as title and author_name), without
+ // providing either the url or html parameters. The consumer may then link to the resource, using the URL
+ // specified in the original request.
+ Link string
+
+ // Rich is used for rich HTML content that does not fall under one of the other categories.
+ Rich struct {
+ // The HTML required to display the resource. The HTML should have no padding or margins.
+ // Consumers may wish to load the HTML in an off-domain iframe to avoid XSS vulnerabilities.
+ // The markup should be valid XHTML 1.0 Basic.
+ HTML string `json:"html"` // required
+
+ // The width in pixels required to display the HTML.
+ Width int `json:"width"` // required
+
+ // The height in pixels required to display the HTML.
+ Height int `json:"height"` // required
+ }
+)
diff --git a/types_ffjson.go b/types_ffjson.go
new file mode 100644
index 0000000..d24413d
--- /dev/null
+++ b/types_ffjson.go
@@ -0,0 +1,2497 @@
+// Code generated by ffjson . DO NOT EDIT.
+// source: types.go
+
+package oembed
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ fflib "github.com/pquerna/ffjson/fflib/v1"
+)
+
+// MarshalJSON marshal bytes to json - template
+func (j *Endpoint) MarshalJSON() ([]byte, error) {
+ var buf fflib.Buffer
+ if j == nil {
+ buf.WriteString("null")
+ return buf.Bytes(), nil
+ }
+ err := j.MarshalJSONBuf(&buf)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// MarshalJSONBuf marshal buff to json - template
+func (j *Endpoint) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
+ if j == nil {
+ buf.WriteString("null")
+ return nil
+ }
+ var err error
+ var obj []byte
+ _ = obj
+ _ = err
+ buf.WriteString(`{ `)
+ if len(j.Schemes) != 0 {
+ buf.WriteString(`"schemes":`)
+ if j.Schemes != nil {
+ buf.WriteString(`[`)
+ for i, v := range j.Schemes {
+ if i != 0 {
+ buf.WriteString(`,`)
+ }
+ fflib.WriteJsonString(buf, string(v))
+ }
+ buf.WriteString(`]`)
+ } else {
+ buf.WriteString(`null`)
+ }
+ buf.WriteByte(',')
+ }
+ buf.WriteString(`"url":`)
+ fflib.WriteJsonString(buf, string(j.URL))
+ buf.WriteByte(',')
+ if j.Discovery != false {
+ if j.Discovery {
+ buf.WriteString(`"discovery":true`)
+ } else {
+ buf.WriteString(`"discovery":false`)
+ }
+ buf.WriteByte(',')
+ }
+ if len(j.Formats) != 0 {
+ buf.WriteString(`"formats":`)
+ if j.Formats != nil {
+ buf.WriteString(`[`)
+ for i, v := range j.Formats {
+ if i != 0 {
+ buf.WriteString(`,`)
+ }
+ fflib.WriteJsonString(buf, string(v))
+ }
+ buf.WriteString(`]`)
+ } else {
+ buf.WriteString(`null`)
+ }
+ buf.WriteByte(',')
+ }
+ buf.Rewind(1)
+ buf.WriteByte('}')
+ return nil
+}
+
+const (
+ ffjtEndpointbase = iota
+ ffjtEndpointnosuchkey
+
+ ffjtEndpointSchemes
+
+ ffjtEndpointURL
+
+ ffjtEndpointDiscovery
+
+ ffjtEndpointFormats
+)
+
+var ffjKeyEndpointSchemes = []byte("schemes")
+
+var ffjKeyEndpointURL = []byte("url")
+
+var ffjKeyEndpointDiscovery = []byte("discovery")
+
+var ffjKeyEndpointFormats = []byte("formats")
+
+// UnmarshalJSON umarshall json - template of ffjson
+func (j *Endpoint) UnmarshalJSON(input []byte) error {
+ fs := fflib.NewFFLexer(input)
+ return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start)
+}
+
+// UnmarshalJSONFFLexer fast json unmarshall - template ffjson
+func (j *Endpoint) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error {
+ var err error
+ currentKey := ffjtEndpointbase
+ _ = currentKey
+ tok := fflib.FFTok_init
+ wantedTok := fflib.FFTok_init
+
+mainparse:
+ for {
+ tok = fs.Scan()
+ // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state))
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+
+ switch state {
+
+ case fflib.FFParse_map_start:
+ if tok != fflib.FFTok_left_bracket {
+ wantedTok = fflib.FFTok_left_bracket
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_key
+ continue
+
+ case fflib.FFParse_after_value:
+ if tok == fflib.FFTok_comma {
+ state = fflib.FFParse_want_key
+ } else if tok == fflib.FFTok_right_bracket {
+ goto done
+ } else {
+ wantedTok = fflib.FFTok_comma
+ goto wrongtokenerror
+ }
+
+ case fflib.FFParse_want_key:
+ // json {} ended. goto exit. woo.
+ if tok == fflib.FFTok_right_bracket {
+ goto done
+ }
+ if tok != fflib.FFTok_string {
+ wantedTok = fflib.FFTok_string
+ goto wrongtokenerror
+ }
+
+ kn := fs.Output.Bytes()
+ if len(kn) <= 0 {
+ // "" case. hrm.
+ currentKey = ffjtEndpointnosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ } else {
+ switch kn[0] {
+
+ case 'd':
+
+ if bytes.Equal(ffjKeyEndpointDiscovery, kn) {
+ currentKey = ffjtEndpointDiscovery
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'f':
+
+ if bytes.Equal(ffjKeyEndpointFormats, kn) {
+ currentKey = ffjtEndpointFormats
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 's':
+
+ if bytes.Equal(ffjKeyEndpointSchemes, kn) {
+ currentKey = ffjtEndpointSchemes
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'u':
+
+ if bytes.Equal(ffjKeyEndpointURL, kn) {
+ currentKey = ffjtEndpointURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ }
+
+ if fflib.EqualFoldRight(ffjKeyEndpointFormats, kn) {
+ currentKey = ffjtEndpointFormats
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.EqualFoldRight(ffjKeyEndpointDiscovery, kn) {
+ currentKey = ffjtEndpointDiscovery
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyEndpointURL, kn) {
+ currentKey = ffjtEndpointURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.EqualFoldRight(ffjKeyEndpointSchemes, kn) {
+ currentKey = ffjtEndpointSchemes
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ currentKey = ffjtEndpointnosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case fflib.FFParse_want_colon:
+ if tok != fflib.FFTok_colon {
+ wantedTok = fflib.FFTok_colon
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_value
+ continue
+ case fflib.FFParse_want_value:
+
+ if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null {
+ switch currentKey {
+
+ case ffjtEndpointSchemes:
+ goto handle_Schemes
+
+ case ffjtEndpointURL:
+ goto handle_URL
+
+ case ffjtEndpointDiscovery:
+ goto handle_Discovery
+
+ case ffjtEndpointFormats:
+ goto handle_Formats
+
+ case ffjtEndpointnosuchkey:
+ err = fs.SkipField(tok)
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ state = fflib.FFParse_after_value
+ goto mainparse
+ }
+ } else {
+ goto wantedvalue
+ }
+ }
+ }
+
+handle_Schemes:
+
+ /* handler: j.Schemes type=[]string kind=slice quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_left_brace && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for ", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+ j.Schemes = nil
+ } else {
+
+ j.Schemes = []string{}
+
+ wantVal := true
+
+ for {
+
+ var tmpJSchemes string
+
+ tok = fs.Scan()
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+ if tok == fflib.FFTok_right_brace {
+ break
+ }
+
+ if tok == fflib.FFTok_comma {
+ if wantVal == true {
+ // TODO(pquerna): this isn't an ideal error message, this handles
+ // things like [,,,] as an array value.
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+ }
+ continue
+ } else {
+ wantVal = true
+ }
+
+ /* handler: tmpJSchemes type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ tmpJSchemes = string(string(outBuf))
+
+ }
+ }
+
+ j.Schemes = append(j.Schemes, tmpJSchemes)
+
+ wantVal = false
+ }
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_URL:
+
+ /* handler: j.URL type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.URL = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Discovery:
+
+ /* handler: j.Discovery type=bool kind=bool quoted=false*/
+
+ {
+ if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
+ }
+ }
+
+ {
+ if tok == fflib.FFTok_null {
+
+ } else {
+ tmpb := fs.Output.Bytes()
+
+ if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
+
+ j.Discovery = true
+
+ } else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
+
+ j.Discovery = false
+
+ } else {
+ err = errors.New("unexpected bytes for true/false value")
+ return fs.WrapErr(err)
+ }
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Formats:
+
+ /* handler: j.Formats type=[]string kind=slice quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_left_brace && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for ", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+ j.Formats = nil
+ } else {
+
+ j.Formats = []string{}
+
+ wantVal := true
+
+ for {
+
+ var tmpJFormats string
+
+ tok = fs.Scan()
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+ if tok == fflib.FFTok_right_brace {
+ break
+ }
+
+ if tok == fflib.FFTok_comma {
+ if wantVal == true {
+ // TODO(pquerna): this isn't an ideal error message, this handles
+ // things like [,,,] as an array value.
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+ }
+ continue
+ } else {
+ wantVal = true
+ }
+
+ /* handler: tmpJFormats type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ tmpJFormats = string(string(outBuf))
+
+ }
+ }
+
+ j.Formats = append(j.Formats, tmpJFormats)
+
+ wantVal = false
+ }
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+wantedvalue:
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+wrongtokenerror:
+ return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String()))
+tokerror:
+ if fs.BigError != nil {
+ return fs.WrapErr(fs.BigError)
+ }
+ err = fs.Error.ToError()
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ panic("ffjson-generated: unreachable, please report bug.")
+done:
+
+ return nil
+}
+
+// MarshalJSON marshal bytes to json - template
+func (j *Photo) MarshalJSON() ([]byte, error) {
+ var buf fflib.Buffer
+ if j == nil {
+ buf.WriteString("null")
+ return buf.Bytes(), nil
+ }
+ err := j.MarshalJSONBuf(&buf)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// MarshalJSONBuf marshal buff to json - template
+func (j *Photo) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
+ if j == nil {
+ buf.WriteString("null")
+ return nil
+ }
+ var err error
+ var obj []byte
+ _ = obj
+ _ = err
+ buf.WriteString(`{"url":`)
+ fflib.WriteJsonString(buf, string(j.URL))
+ buf.WriteString(`,"width":`)
+ fflib.FormatBits2(buf, uint64(j.Width), 10, j.Width < 0)
+ buf.WriteString(`,"height":`)
+ fflib.FormatBits2(buf, uint64(j.Height), 10, j.Height < 0)
+ buf.WriteByte('}')
+ return nil
+}
+
+const (
+ ffjtPhotobase = iota
+ ffjtPhotonosuchkey
+
+ ffjtPhotoURL
+
+ ffjtPhotoWidth
+
+ ffjtPhotoHeight
+)
+
+var ffjKeyPhotoURL = []byte("url")
+
+var ffjKeyPhotoWidth = []byte("width")
+
+var ffjKeyPhotoHeight = []byte("height")
+
+// UnmarshalJSON umarshall json - template of ffjson
+func (j *Photo) UnmarshalJSON(input []byte) error {
+ fs := fflib.NewFFLexer(input)
+ return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start)
+}
+
+// UnmarshalJSONFFLexer fast json unmarshall - template ffjson
+func (j *Photo) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error {
+ var err error
+ currentKey := ffjtPhotobase
+ _ = currentKey
+ tok := fflib.FFTok_init
+ wantedTok := fflib.FFTok_init
+
+mainparse:
+ for {
+ tok = fs.Scan()
+ // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state))
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+
+ switch state {
+
+ case fflib.FFParse_map_start:
+ if tok != fflib.FFTok_left_bracket {
+ wantedTok = fflib.FFTok_left_bracket
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_key
+ continue
+
+ case fflib.FFParse_after_value:
+ if tok == fflib.FFTok_comma {
+ state = fflib.FFParse_want_key
+ } else if tok == fflib.FFTok_right_bracket {
+ goto done
+ } else {
+ wantedTok = fflib.FFTok_comma
+ goto wrongtokenerror
+ }
+
+ case fflib.FFParse_want_key:
+ // json {} ended. goto exit. woo.
+ if tok == fflib.FFTok_right_bracket {
+ goto done
+ }
+ if tok != fflib.FFTok_string {
+ wantedTok = fflib.FFTok_string
+ goto wrongtokenerror
+ }
+
+ kn := fs.Output.Bytes()
+ if len(kn) <= 0 {
+ // "" case. hrm.
+ currentKey = ffjtPhotonosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ } else {
+ switch kn[0] {
+
+ case 'h':
+
+ if bytes.Equal(ffjKeyPhotoHeight, kn) {
+ currentKey = ffjtPhotoHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'u':
+
+ if bytes.Equal(ffjKeyPhotoURL, kn) {
+ currentKey = ffjtPhotoURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'w':
+
+ if bytes.Equal(ffjKeyPhotoWidth, kn) {
+ currentKey = ffjtPhotoWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyPhotoHeight, kn) {
+ currentKey = ffjtPhotoHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyPhotoWidth, kn) {
+ currentKey = ffjtPhotoWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyPhotoURL, kn) {
+ currentKey = ffjtPhotoURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ currentKey = ffjtPhotonosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case fflib.FFParse_want_colon:
+ if tok != fflib.FFTok_colon {
+ wantedTok = fflib.FFTok_colon
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_value
+ continue
+ case fflib.FFParse_want_value:
+
+ if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null {
+ switch currentKey {
+
+ case ffjtPhotoURL:
+ goto handle_URL
+
+ case ffjtPhotoWidth:
+ goto handle_Width
+
+ case ffjtPhotoHeight:
+ goto handle_Height
+
+ case ffjtPhotonosuchkey:
+ err = fs.SkipField(tok)
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ state = fflib.FFParse_after_value
+ goto mainparse
+ }
+ } else {
+ goto wantedvalue
+ }
+ }
+ }
+
+handle_URL:
+
+ /* handler: j.URL type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.URL = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Width:
+
+ /* handler: j.Width type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.Width = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Height:
+
+ /* handler: j.Height type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.Height = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+wantedvalue:
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+wrongtokenerror:
+ return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String()))
+tokerror:
+ if fs.BigError != nil {
+ return fs.WrapErr(fs.BigError)
+ }
+ err = fs.Error.ToError()
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ panic("ffjson-generated: unreachable, please report bug.")
+done:
+
+ return nil
+}
+
+// MarshalJSON marshal bytes to json - template
+func (j *Provider) MarshalJSON() ([]byte, error) {
+ var buf fflib.Buffer
+ if j == nil {
+ buf.WriteString("null")
+ return buf.Bytes(), nil
+ }
+ err := j.MarshalJSONBuf(&buf)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// MarshalJSONBuf marshal buff to json - template
+func (j *Provider) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
+ if j == nil {
+ buf.WriteString("null")
+ return nil
+ }
+ var err error
+ var obj []byte
+ _ = obj
+ _ = err
+ buf.WriteString(`{"provider_name":`)
+ fflib.WriteJsonString(buf, string(j.Name))
+ buf.WriteString(`,"provider_url":`)
+ fflib.WriteJsonString(buf, string(j.URL))
+ buf.WriteString(`,"endpoints":`)
+ if j.Endpoints != nil {
+ buf.WriteString(`[`)
+ for i, v := range j.Endpoints {
+ if i != 0 {
+ buf.WriteString(`,`)
+ }
+
+ {
+
+ err = v.MarshalJSONBuf(buf)
+ if err != nil {
+ return err
+ }
+
+ }
+ }
+ buf.WriteString(`]`)
+ } else {
+ buf.WriteString(`null`)
+ }
+ buf.WriteByte('}')
+ return nil
+}
+
+const (
+ ffjtProviderbase = iota
+ ffjtProvidernosuchkey
+
+ ffjtProviderName
+
+ ffjtProviderURL
+
+ ffjtProviderEndpoints
+)
+
+var ffjKeyProviderName = []byte("provider_name")
+
+var ffjKeyProviderURL = []byte("provider_url")
+
+var ffjKeyProviderEndpoints = []byte("endpoints")
+
+// UnmarshalJSON umarshall json - template of ffjson
+func (j *Provider) UnmarshalJSON(input []byte) error {
+ fs := fflib.NewFFLexer(input)
+ return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start)
+}
+
+// UnmarshalJSONFFLexer fast json unmarshall - template ffjson
+func (j *Provider) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error {
+ var err error
+ currentKey := ffjtProviderbase
+ _ = currentKey
+ tok := fflib.FFTok_init
+ wantedTok := fflib.FFTok_init
+
+mainparse:
+ for {
+ tok = fs.Scan()
+ // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state))
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+
+ switch state {
+
+ case fflib.FFParse_map_start:
+ if tok != fflib.FFTok_left_bracket {
+ wantedTok = fflib.FFTok_left_bracket
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_key
+ continue
+
+ case fflib.FFParse_after_value:
+ if tok == fflib.FFTok_comma {
+ state = fflib.FFParse_want_key
+ } else if tok == fflib.FFTok_right_bracket {
+ goto done
+ } else {
+ wantedTok = fflib.FFTok_comma
+ goto wrongtokenerror
+ }
+
+ case fflib.FFParse_want_key:
+ // json {} ended. goto exit. woo.
+ if tok == fflib.FFTok_right_bracket {
+ goto done
+ }
+ if tok != fflib.FFTok_string {
+ wantedTok = fflib.FFTok_string
+ goto wrongtokenerror
+ }
+
+ kn := fs.Output.Bytes()
+ if len(kn) <= 0 {
+ // "" case. hrm.
+ currentKey = ffjtProvidernosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ } else {
+ switch kn[0] {
+
+ case 'e':
+
+ if bytes.Equal(ffjKeyProviderEndpoints, kn) {
+ currentKey = ffjtProviderEndpoints
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'p':
+
+ if bytes.Equal(ffjKeyProviderName, kn) {
+ currentKey = ffjtProviderName
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyProviderURL, kn) {
+ currentKey = ffjtProviderURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ }
+
+ if fflib.EqualFoldRight(ffjKeyProviderEndpoints, kn) {
+ currentKey = ffjtProviderEndpoints
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyProviderURL, kn) {
+ currentKey = ffjtProviderURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyProviderName, kn) {
+ currentKey = ffjtProviderName
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ currentKey = ffjtProvidernosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case fflib.FFParse_want_colon:
+ if tok != fflib.FFTok_colon {
+ wantedTok = fflib.FFTok_colon
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_value
+ continue
+ case fflib.FFParse_want_value:
+
+ if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null {
+ switch currentKey {
+
+ case ffjtProviderName:
+ goto handle_Name
+
+ case ffjtProviderURL:
+ goto handle_URL
+
+ case ffjtProviderEndpoints:
+ goto handle_Endpoints
+
+ case ffjtProvidernosuchkey:
+ err = fs.SkipField(tok)
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ state = fflib.FFParse_after_value
+ goto mainparse
+ }
+ } else {
+ goto wantedvalue
+ }
+ }
+ }
+
+handle_Name:
+
+ /* handler: j.Name type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.Name = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_URL:
+
+ /* handler: j.URL type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.URL = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Endpoints:
+
+ /* handler: j.Endpoints type=[]oembed.Endpoint kind=slice quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_left_brace && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for ", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+ j.Endpoints = nil
+ } else {
+
+ j.Endpoints = []Endpoint{}
+
+ wantVal := true
+
+ for {
+
+ var tmpJEndpoints Endpoint
+
+ tok = fs.Scan()
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+ if tok == fflib.FFTok_right_brace {
+ break
+ }
+
+ if tok == fflib.FFTok_comma {
+ if wantVal == true {
+ // TODO(pquerna): this isn't an ideal error message, this handles
+ // things like [,,,] as an array value.
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+ }
+ continue
+ } else {
+ wantVal = true
+ }
+
+ /* handler: tmpJEndpoints type=oembed.Endpoint kind=struct quoted=false*/
+
+ {
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ err = tmpJEndpoints.UnmarshalJSONFFLexer(fs, fflib.FFParse_want_key)
+ if err != nil {
+ return err
+ }
+ }
+ state = fflib.FFParse_after_value
+ }
+
+ j.Endpoints = append(j.Endpoints, tmpJEndpoints)
+
+ wantVal = false
+ }
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+wantedvalue:
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+wrongtokenerror:
+ return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String()))
+tokerror:
+ if fs.BigError != nil {
+ return fs.WrapErr(fs.BigError)
+ }
+ err = fs.Error.ToError()
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ panic("ffjson-generated: unreachable, please report bug.")
+done:
+
+ return nil
+}
+
+// MarshalJSON marshal bytes to json - template
+func (j *Response) MarshalJSON() ([]byte, error) {
+ var buf fflib.Buffer
+ if j == nil {
+ buf.WriteString("null")
+ return buf.Bytes(), nil
+ }
+ err := j.MarshalJSONBuf(&buf)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// MarshalJSONBuf marshal buff to json - template
+func (j *Response) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
+ if j == nil {
+ buf.WriteString("null")
+ return nil
+ }
+ var err error
+ var obj []byte
+ _ = obj
+ _ = err
+ buf.WriteString(`{ "type":`)
+ fflib.WriteJsonString(buf, string(j.Type))
+ buf.WriteString(`,"version":`)
+ fflib.WriteJsonString(buf, string(j.Version))
+ buf.WriteByte(',')
+ if len(j.Title) != 0 {
+ buf.WriteString(`"title":`)
+ fflib.WriteJsonString(buf, string(j.Title))
+ buf.WriteByte(',')
+ }
+ if len(j.AuthorName) != 0 {
+ buf.WriteString(`"author_name":`)
+ fflib.WriteJsonString(buf, string(j.AuthorName))
+ buf.WriteByte(',')
+ }
+ if len(j.AuthorURL) != 0 {
+ buf.WriteString(`"author_url":`)
+ fflib.WriteJsonString(buf, string(j.AuthorURL))
+ buf.WriteByte(',')
+ }
+ if len(j.ProviderName) != 0 {
+ buf.WriteString(`"provider_name":`)
+ fflib.WriteJsonString(buf, string(j.ProviderName))
+ buf.WriteByte(',')
+ }
+ if len(j.ProviderURL) != 0 {
+ buf.WriteString(`"provider_url":`)
+ fflib.WriteJsonString(buf, string(j.ProviderURL))
+ buf.WriteByte(',')
+ }
+ if j.CacheAge != 0 {
+ buf.WriteString(`"cache_age":`)
+ fflib.FormatBits2(buf, uint64(j.CacheAge), 10, j.CacheAge < 0)
+ buf.WriteByte(',')
+ }
+ if len(j.ThumbnailURL) != 0 {
+ buf.WriteString(`"thumbnail_url":`)
+ fflib.WriteJsonString(buf, string(j.ThumbnailURL))
+ buf.WriteByte(',')
+ }
+ if j.ThumbnailWidth != 0 {
+ buf.WriteString(`"thumbnail_width":`)
+ fflib.FormatBits2(buf, uint64(j.ThumbnailWidth), 10, j.ThumbnailWidth < 0)
+ buf.WriteByte(',')
+ }
+ if j.ThumbnailHeight != 0 {
+ buf.WriteString(`"thumbnail_height":`)
+ fflib.FormatBits2(buf, uint64(j.ThumbnailHeight), 10, j.ThumbnailHeight < 0)
+ buf.WriteByte(',')
+ }
+ if len(j.URL) != 0 {
+ buf.WriteString(`"url":`)
+ fflib.WriteJsonString(buf, string(j.URL))
+ buf.WriteByte(',')
+ }
+ buf.Rewind(1)
+ buf.WriteByte('}')
+ return nil
+}
+
+const (
+ ffjtResponsebase = iota
+ ffjtResponsenosuchkey
+
+ ffjtResponseType
+
+ ffjtResponseVersion
+
+ ffjtResponseTitle
+
+ ffjtResponseAuthorName
+
+ ffjtResponseAuthorURL
+
+ ffjtResponseProviderName
+
+ ffjtResponseProviderURL
+
+ ffjtResponseCacheAge
+
+ ffjtResponseThumbnailURL
+
+ ffjtResponseThumbnailWidth
+
+ ffjtResponseThumbnailHeight
+
+ ffjtResponseURL
+)
+
+var ffjKeyResponseType = []byte("type")
+
+var ffjKeyResponseVersion = []byte("version")
+
+var ffjKeyResponseTitle = []byte("title")
+
+var ffjKeyResponseAuthorName = []byte("author_name")
+
+var ffjKeyResponseAuthorURL = []byte("author_url")
+
+var ffjKeyResponseProviderName = []byte("provider_name")
+
+var ffjKeyResponseProviderURL = []byte("provider_url")
+
+var ffjKeyResponseCacheAge = []byte("cache_age")
+
+var ffjKeyResponseThumbnailURL = []byte("thumbnail_url")
+
+var ffjKeyResponseThumbnailWidth = []byte("thumbnail_width")
+
+var ffjKeyResponseThumbnailHeight = []byte("thumbnail_height")
+
+var ffjKeyResponseURL = []byte("url")
+
+// UnmarshalJSON umarshall json - template of ffjson
+func (j *Response) UnmarshalJSON(input []byte) error {
+ fs := fflib.NewFFLexer(input)
+ return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start)
+}
+
+// UnmarshalJSONFFLexer fast json unmarshall - template ffjson
+func (j *Response) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error {
+ var err error
+ currentKey := ffjtResponsebase
+ _ = currentKey
+ tok := fflib.FFTok_init
+ wantedTok := fflib.FFTok_init
+
+mainparse:
+ for {
+ tok = fs.Scan()
+ // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state))
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+
+ switch state {
+
+ case fflib.FFParse_map_start:
+ if tok != fflib.FFTok_left_bracket {
+ wantedTok = fflib.FFTok_left_bracket
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_key
+ continue
+
+ case fflib.FFParse_after_value:
+ if tok == fflib.FFTok_comma {
+ state = fflib.FFParse_want_key
+ } else if tok == fflib.FFTok_right_bracket {
+ goto done
+ } else {
+ wantedTok = fflib.FFTok_comma
+ goto wrongtokenerror
+ }
+
+ case fflib.FFParse_want_key:
+ // json {} ended. goto exit. woo.
+ if tok == fflib.FFTok_right_bracket {
+ goto done
+ }
+ if tok != fflib.FFTok_string {
+ wantedTok = fflib.FFTok_string
+ goto wrongtokenerror
+ }
+
+ kn := fs.Output.Bytes()
+ if len(kn) <= 0 {
+ // "" case. hrm.
+ currentKey = ffjtResponsenosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ } else {
+ switch kn[0] {
+
+ case 'a':
+
+ if bytes.Equal(ffjKeyResponseAuthorName, kn) {
+ currentKey = ffjtResponseAuthorName
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyResponseAuthorURL, kn) {
+ currentKey = ffjtResponseAuthorURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'c':
+
+ if bytes.Equal(ffjKeyResponseCacheAge, kn) {
+ currentKey = ffjtResponseCacheAge
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'p':
+
+ if bytes.Equal(ffjKeyResponseProviderName, kn) {
+ currentKey = ffjtResponseProviderName
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyResponseProviderURL, kn) {
+ currentKey = ffjtResponseProviderURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 't':
+
+ if bytes.Equal(ffjKeyResponseType, kn) {
+ currentKey = ffjtResponseType
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyResponseTitle, kn) {
+ currentKey = ffjtResponseTitle
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyResponseThumbnailURL, kn) {
+ currentKey = ffjtResponseThumbnailURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyResponseThumbnailWidth, kn) {
+ currentKey = ffjtResponseThumbnailWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyResponseThumbnailHeight, kn) {
+ currentKey = ffjtResponseThumbnailHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'u':
+
+ if bytes.Equal(ffjKeyResponseURL, kn) {
+ currentKey = ffjtResponseURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'v':
+
+ if bytes.Equal(ffjKeyResponseVersion, kn) {
+ currentKey = ffjtResponseVersion
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyResponseURL, kn) {
+ currentKey = ffjtResponseURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseThumbnailHeight, kn) {
+ currentKey = ffjtResponseThumbnailHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseThumbnailWidth, kn) {
+ currentKey = ffjtResponseThumbnailWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseThumbnailURL, kn) {
+ currentKey = ffjtResponseThumbnailURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseCacheAge, kn) {
+ currentKey = ffjtResponseCacheAge
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseProviderURL, kn) {
+ currentKey = ffjtResponseProviderURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseProviderName, kn) {
+ currentKey = ffjtResponseProviderName
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseAuthorURL, kn) {
+ currentKey = ffjtResponseAuthorURL
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.AsciiEqualFold(ffjKeyResponseAuthorName, kn) {
+ currentKey = ffjtResponseAuthorName
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyResponseTitle, kn) {
+ currentKey = ffjtResponseTitle
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.EqualFoldRight(ffjKeyResponseVersion, kn) {
+ currentKey = ffjtResponseVersion
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyResponseType, kn) {
+ currentKey = ffjtResponseType
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ currentKey = ffjtResponsenosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case fflib.FFParse_want_colon:
+ if tok != fflib.FFTok_colon {
+ wantedTok = fflib.FFTok_colon
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_value
+ continue
+ case fflib.FFParse_want_value:
+
+ if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null {
+ switch currentKey {
+
+ case ffjtResponseType:
+ goto handle_Type
+
+ case ffjtResponseVersion:
+ goto handle_Version
+
+ case ffjtResponseTitle:
+ goto handle_Title
+
+ case ffjtResponseAuthorName:
+ goto handle_AuthorName
+
+ case ffjtResponseAuthorURL:
+ goto handle_AuthorURL
+
+ case ffjtResponseProviderName:
+ goto handle_ProviderName
+
+ case ffjtResponseProviderURL:
+ goto handle_ProviderURL
+
+ case ffjtResponseCacheAge:
+ goto handle_CacheAge
+
+ case ffjtResponseThumbnailURL:
+ goto handle_ThumbnailURL
+
+ case ffjtResponseThumbnailWidth:
+ goto handle_ThumbnailWidth
+
+ case ffjtResponseThumbnailHeight:
+ goto handle_ThumbnailHeight
+
+ case ffjtResponseURL:
+ goto handle_URL
+
+ case ffjtResponsenosuchkey:
+ err = fs.SkipField(tok)
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ state = fflib.FFParse_after_value
+ goto mainparse
+ }
+ } else {
+ goto wantedvalue
+ }
+ }
+ }
+
+handle_Type:
+
+ /* handler: j.Type type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.Type = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Version:
+
+ /* handler: j.Version type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.Version = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Title:
+
+ /* handler: j.Title type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.Title = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_AuthorName:
+
+ /* handler: j.AuthorName type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.AuthorName = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_AuthorURL:
+
+ /* handler: j.AuthorURL type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.AuthorURL = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_ProviderName:
+
+ /* handler: j.ProviderName type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.ProviderName = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_ProviderURL:
+
+ /* handler: j.ProviderURL type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.ProviderURL = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_CacheAge:
+
+ /* handler: j.CacheAge type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.CacheAge = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_ThumbnailURL:
+
+ /* handler: j.ThumbnailURL type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.ThumbnailURL = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_ThumbnailWidth:
+
+ /* handler: j.ThumbnailWidth type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.ThumbnailWidth = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_ThumbnailHeight:
+
+ /* handler: j.ThumbnailHeight type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.ThumbnailHeight = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_URL:
+
+ /* handler: j.URL type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.URL = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+wantedvalue:
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+wrongtokenerror:
+ return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String()))
+tokerror:
+ if fs.BigError != nil {
+ return fs.WrapErr(fs.BigError)
+ }
+ err = fs.Error.ToError()
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ panic("ffjson-generated: unreachable, please report bug.")
+done:
+
+ return nil
+}
+
+// MarshalJSON marshal bytes to json - template
+func (j *Rich) MarshalJSON() ([]byte, error) {
+ var buf fflib.Buffer
+ if j == nil {
+ buf.WriteString("null")
+ return buf.Bytes(), nil
+ }
+ err := j.MarshalJSONBuf(&buf)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// MarshalJSONBuf marshal buff to json - template
+func (j *Rich) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
+ if j == nil {
+ buf.WriteString("null")
+ return nil
+ }
+ var err error
+ var obj []byte
+ _ = obj
+ _ = err
+ buf.WriteString(`{"html":`)
+ fflib.WriteJsonString(buf, string(j.HTML))
+ buf.WriteString(`,"width":`)
+ fflib.FormatBits2(buf, uint64(j.Width), 10, j.Width < 0)
+ buf.WriteString(`,"height":`)
+ fflib.FormatBits2(buf, uint64(j.Height), 10, j.Height < 0)
+ buf.WriteByte('}')
+ return nil
+}
+
+const (
+ ffjtRichbase = iota
+ ffjtRichnosuchkey
+
+ ffjtRichHTML
+
+ ffjtRichWidth
+
+ ffjtRichHeight
+)
+
+var ffjKeyRichHTML = []byte("html")
+
+var ffjKeyRichWidth = []byte("width")
+
+var ffjKeyRichHeight = []byte("height")
+
+// UnmarshalJSON umarshall json - template of ffjson
+func (j *Rich) UnmarshalJSON(input []byte) error {
+ fs := fflib.NewFFLexer(input)
+ return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start)
+}
+
+// UnmarshalJSONFFLexer fast json unmarshall - template ffjson
+func (j *Rich) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error {
+ var err error
+ currentKey := ffjtRichbase
+ _ = currentKey
+ tok := fflib.FFTok_init
+ wantedTok := fflib.FFTok_init
+
+mainparse:
+ for {
+ tok = fs.Scan()
+ // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state))
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+
+ switch state {
+
+ case fflib.FFParse_map_start:
+ if tok != fflib.FFTok_left_bracket {
+ wantedTok = fflib.FFTok_left_bracket
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_key
+ continue
+
+ case fflib.FFParse_after_value:
+ if tok == fflib.FFTok_comma {
+ state = fflib.FFParse_want_key
+ } else if tok == fflib.FFTok_right_bracket {
+ goto done
+ } else {
+ wantedTok = fflib.FFTok_comma
+ goto wrongtokenerror
+ }
+
+ case fflib.FFParse_want_key:
+ // json {} ended. goto exit. woo.
+ if tok == fflib.FFTok_right_bracket {
+ goto done
+ }
+ if tok != fflib.FFTok_string {
+ wantedTok = fflib.FFTok_string
+ goto wrongtokenerror
+ }
+
+ kn := fs.Output.Bytes()
+ if len(kn) <= 0 {
+ // "" case. hrm.
+ currentKey = ffjtRichnosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ } else {
+ switch kn[0] {
+
+ case 'h':
+
+ if bytes.Equal(ffjKeyRichHTML, kn) {
+ currentKey = ffjtRichHTML
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyRichHeight, kn) {
+ currentKey = ffjtRichHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'w':
+
+ if bytes.Equal(ffjKeyRichWidth, kn) {
+ currentKey = ffjtRichWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyRichHeight, kn) {
+ currentKey = ffjtRichHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyRichWidth, kn) {
+ currentKey = ffjtRichWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyRichHTML, kn) {
+ currentKey = ffjtRichHTML
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ currentKey = ffjtRichnosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case fflib.FFParse_want_colon:
+ if tok != fflib.FFTok_colon {
+ wantedTok = fflib.FFTok_colon
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_value
+ continue
+ case fflib.FFParse_want_value:
+
+ if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null {
+ switch currentKey {
+
+ case ffjtRichHTML:
+ goto handle_HTML
+
+ case ffjtRichWidth:
+ goto handle_Width
+
+ case ffjtRichHeight:
+ goto handle_Height
+
+ case ffjtRichnosuchkey:
+ err = fs.SkipField(tok)
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ state = fflib.FFParse_after_value
+ goto mainparse
+ }
+ } else {
+ goto wantedvalue
+ }
+ }
+ }
+
+handle_HTML:
+
+ /* handler: j.HTML type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.HTML = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Width:
+
+ /* handler: j.Width type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.Width = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Height:
+
+ /* handler: j.Height type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.Height = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+wantedvalue:
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+wrongtokenerror:
+ return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String()))
+tokerror:
+ if fs.BigError != nil {
+ return fs.WrapErr(fs.BigError)
+ }
+ err = fs.Error.ToError()
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ panic("ffjson-generated: unreachable, please report bug.")
+done:
+
+ return nil
+}
+
+// MarshalJSON marshal bytes to json - template
+func (j *Video) MarshalJSON() ([]byte, error) {
+ var buf fflib.Buffer
+ if j == nil {
+ buf.WriteString("null")
+ return buf.Bytes(), nil
+ }
+ err := j.MarshalJSONBuf(&buf)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+// MarshalJSONBuf marshal buff to json - template
+func (j *Video) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
+ if j == nil {
+ buf.WriteString("null")
+ return nil
+ }
+ var err error
+ var obj []byte
+ _ = obj
+ _ = err
+ buf.WriteString(`{"html":`)
+ fflib.WriteJsonString(buf, string(j.HTML))
+ buf.WriteString(`,"width":`)
+ fflib.FormatBits2(buf, uint64(j.Width), 10, j.Width < 0)
+ buf.WriteString(`,"height":`)
+ fflib.FormatBits2(buf, uint64(j.Height), 10, j.Height < 0)
+ buf.WriteByte('}')
+ return nil
+}
+
+const (
+ ffjtVideobase = iota
+ ffjtVideonosuchkey
+
+ ffjtVideoHTML
+
+ ffjtVideoWidth
+
+ ffjtVideoHeight
+)
+
+var ffjKeyVideoHTML = []byte("html")
+
+var ffjKeyVideoWidth = []byte("width")
+
+var ffjKeyVideoHeight = []byte("height")
+
+// UnmarshalJSON umarshall json - template of ffjson
+func (j *Video) UnmarshalJSON(input []byte) error {
+ fs := fflib.NewFFLexer(input)
+ return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start)
+}
+
+// UnmarshalJSONFFLexer fast json unmarshall - template ffjson
+func (j *Video) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error {
+ var err error
+ currentKey := ffjtVideobase
+ _ = currentKey
+ tok := fflib.FFTok_init
+ wantedTok := fflib.FFTok_init
+
+mainparse:
+ for {
+ tok = fs.Scan()
+ // println(fmt.Sprintf("debug: tok: %v state: %v", tok, state))
+ if tok == fflib.FFTok_error {
+ goto tokerror
+ }
+
+ switch state {
+
+ case fflib.FFParse_map_start:
+ if tok != fflib.FFTok_left_bracket {
+ wantedTok = fflib.FFTok_left_bracket
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_key
+ continue
+
+ case fflib.FFParse_after_value:
+ if tok == fflib.FFTok_comma {
+ state = fflib.FFParse_want_key
+ } else if tok == fflib.FFTok_right_bracket {
+ goto done
+ } else {
+ wantedTok = fflib.FFTok_comma
+ goto wrongtokenerror
+ }
+
+ case fflib.FFParse_want_key:
+ // json {} ended. goto exit. woo.
+ if tok == fflib.FFTok_right_bracket {
+ goto done
+ }
+ if tok != fflib.FFTok_string {
+ wantedTok = fflib.FFTok_string
+ goto wrongtokenerror
+ }
+
+ kn := fs.Output.Bytes()
+ if len(kn) <= 0 {
+ // "" case. hrm.
+ currentKey = ffjtVideonosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ } else {
+ switch kn[0] {
+
+ case 'h':
+
+ if bytes.Equal(ffjKeyVideoHTML, kn) {
+ currentKey = ffjtVideoHTML
+ state = fflib.FFParse_want_colon
+ goto mainparse
+
+ } else if bytes.Equal(ffjKeyVideoHeight, kn) {
+ currentKey = ffjtVideoHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case 'w':
+
+ if bytes.Equal(ffjKeyVideoWidth, kn) {
+ currentKey = ffjtVideoWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyVideoHeight, kn) {
+ currentKey = ffjtVideoHeight
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyVideoWidth, kn) {
+ currentKey = ffjtVideoWidth
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ if fflib.SimpleLetterEqualFold(ffjKeyVideoHTML, kn) {
+ currentKey = ffjtVideoHTML
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ currentKey = ffjtVideonosuchkey
+ state = fflib.FFParse_want_colon
+ goto mainparse
+ }
+
+ case fflib.FFParse_want_colon:
+ if tok != fflib.FFTok_colon {
+ wantedTok = fflib.FFTok_colon
+ goto wrongtokenerror
+ }
+ state = fflib.FFParse_want_value
+ continue
+ case fflib.FFParse_want_value:
+
+ if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null {
+ switch currentKey {
+
+ case ffjtVideoHTML:
+ goto handle_HTML
+
+ case ffjtVideoWidth:
+ goto handle_Width
+
+ case ffjtVideoHeight:
+ goto handle_Height
+
+ case ffjtVideonosuchkey:
+ err = fs.SkipField(tok)
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ state = fflib.FFParse_after_value
+ goto mainparse
+ }
+ } else {
+ goto wantedvalue
+ }
+ }
+ }
+
+handle_HTML:
+
+ /* handler: j.HTML type=string kind=string quoted=false*/
+
+ {
+
+ {
+ if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
+ }
+ }
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ outBuf := fs.Output.Bytes()
+
+ j.HTML = string(string(outBuf))
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Width:
+
+ /* handler: j.Width type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.Width = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+handle_Height:
+
+ /* handler: j.Height type=int kind=int quoted=false*/
+
+ {
+ if tok != fflib.FFTok_integer && tok != fflib.FFTok_null {
+ return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for int", tok))
+ }
+ }
+
+ {
+
+ if tok == fflib.FFTok_null {
+
+ } else {
+
+ tval, err := fflib.ParseInt(fs.Output.Bytes(), 10, 64)
+
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+
+ j.Height = int(tval)
+
+ }
+ }
+
+ state = fflib.FFParse_after_value
+ goto mainparse
+
+wantedvalue:
+ return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
+wrongtokenerror:
+ return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String()))
+tokerror:
+ if fs.BigError != nil {
+ return fs.WrapErr(fs.BigError)
+ }
+ err = fs.Error.ToError()
+ if err != nil {
+ return fs.WrapErr(err)
+ }
+ panic("ffjson-generated: unreachable, please report bug.")
+done:
+
+ return nil
+}