From 67dd384e1cfbc22ebf535bfe71531a7f20546218 Mon Sep 17 00:00:00 2001 From: Charles Iliya Krempeaux Date: Tue, 26 Sep 2023 13:21:46 +0900 Subject: [PATCH] initial commits --- customemoji.go | 74 ++++++++++++++++++ customemoji_marshaljson_test.go | 133 ++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 customemoji.go create mode 100644 customemoji_marshaljson_test.go diff --git a/customemoji.go b/customemoji.go new file mode 100644 index 0000000..4361325 --- /dev/null +++ b/customemoji.go @@ -0,0 +1,74 @@ +package mstdn + +import ( + "encoding/json" + + "sourcecode.social/reiver/go-erorr" + "sourcecode.social/reiver/go-opt" +) + +var _ json.Marshaler = CustomEmoji{} + +const ( + errCannotMashalCustomEmojiAsJSONNoShortCode = erorr.Error("cannot marshal mstdn.Emoji to JSON — no ‘shortcode’ set") + errCannotMashalCustomEmojiAsJSONNoURL = erorr.Error("cannot marshal mstdn.Emoji to JSON — no ‘url’ set") + errCannotMashalCustomEmojiAsJSONNoStaticURL = erorr.Error("cannot marshal mstdn.Emoji to JSON — no ‘static_url’ set") + errCannotMashalCustomEmojiAsJSONNoVisibleInPicker = erorr.Error("cannot marshal mstdn.Emoji to JSON — no ‘visible_in_picker’ set") +) + +// CustomEmoji represents a Mastodon API "CustomEmoji". +// +// See: +// https://docs.joinmastodon.org/entities/CustomEmoji/ +type CustomEmoji struct { + ShortCode opt.Optional[string] `json:"shortcode"` + URL opt.Optional[string] `json:"url"` + StaticURL opt.Optional[string] `json:"static_url"` + VisibleInPicker opt.Optional[bool] `json:"visible_in_picker"` + Category opt.Optional[string] `json:"category"` +} + +func (receiver CustomEmoji) MarshalJSON() ([]byte, error) { + + data := map[string]interface{}{} + + { + value, found := receiver.ShortCode.Get() + if !found { + return nil, errCannotMashalCustomEmojiAsJSONNoShortCode + } + + data["shortcode"] = value + } + { + value, found := receiver.URL.Get() + if !found { + return nil, errCannotMashalCustomEmojiAsJSONNoURL + } + + data["url"] = value + } + { + value, found := receiver.StaticURL.Get() + if !found { + return nil, errCannotMashalCustomEmojiAsJSONNoStaticURL + } + + data["static_url"] = value + } + { + value, found := receiver.VisibleInPicker.Get() + if !found { + return nil, errCannotMashalCustomEmojiAsJSONNoVisibleInPicker + } + + data["visible_in_picker"] = value + } + { + receiver.Category.WhenSomething(func(value string){ + data["category"] = value + }) + } + + return json.Marshal(data) +} diff --git a/customemoji_marshaljson_test.go b/customemoji_marshaljson_test.go new file mode 100644 index 0000000..264c3e2 --- /dev/null +++ b/customemoji_marshaljson_test.go @@ -0,0 +1,133 @@ +package mstdn + +import ( + "testing" + + "bytes" + "encoding/json" + + "sourcecode.social/reiver/go-opt" +) + +func TestCustomEmoji_MarshalJSON(t *testing.T) { + + tests := []struct{ + Value CustomEmoji + Expected string + }{ + { + Value: CustomEmoji{ + ShortCode: opt.Something[string](""), + URL: opt.Something[string](""), + StaticURL: opt.Something[string](""), + VisibleInPicker: opt.Something[bool](false), + }, + Expected: + "{" +"\n"+ + "\t"+ `"shortcode":` +`""` +"," +"\n"+ + "\t"+ `"static_url":` +`""` +"," +"\n"+ + "\t"+ `"url":` +`""` +"," +"\n"+ + "\t"+ `"visible_in_picker":` +`false` +"" +"\n"+ + "}" +"\n", + }, + + + + { + Value: CustomEmoji{ + ShortCode: opt.Something[string]("bananas"), + URL: opt.Something[string](""), + StaticURL: opt.Something[string](""), + VisibleInPicker: opt.Something[bool](false), + }, + Expected: + "{" +"\n"+ + "\t"+ `"shortcode":` +`"bananas"` +"," +"\n"+ + "\t"+ `"static_url":` +`""` +"," +"\n"+ + "\t"+ `"url":` +`""` +"," +"\n"+ + "\t"+ `"visible_in_picker":` +`false` +"" +"\n"+ + "}" +"\n", + }, + { + Value: CustomEmoji{ + ShortCode: opt.Something[string](""), + URL: opt.Something[string]("https://example.com/emoji/cracra"), + StaticURL: opt.Something[string](""), + VisibleInPicker: opt.Something[bool](false), + }, + Expected: + "{" +"\n"+ + "\t"+ `"shortcode":` +`""` +"," +"\n"+ + "\t"+ `"static_url":` +`""` +"," +"\n"+ + "\t"+ `"url":` +`"https://example.com/emoji/cracra"` +"," +"\n"+ + "\t"+ `"visible_in_picker":` +`false` +"" +"\n"+ + "}" +"\n", + }, + { + Value: CustomEmoji{ + ShortCode: opt.Something[string](""), + URL: opt.Something[string](""), + StaticURL: opt.Something[string]("https://static.example.com/img/emoji/cracra.png"), + VisibleInPicker: opt.Something[bool](false), + }, + Expected: + "{" +"\n"+ + "\t"+ `"shortcode":` +`""` +"," +"\n"+ + "\t"+ `"static_url":` +`"https://static.example.com/img/emoji/cracra.png"` +"," +"\n"+ + "\t"+ `"url":` +`""` +"," +"\n"+ + "\t"+ `"visible_in_picker":` +`false` +"" +"\n"+ + "}" +"\n", + }, + { + Value: CustomEmoji{ + ShortCode: opt.Something[string](""), + URL: opt.Something[string](""), + StaticURL: opt.Something[string](""), + VisibleInPicker: opt.Something[bool](true), + }, + Expected: + "{" +"\n"+ + "\t"+ `"shortcode":` +`""` +"," +"\n"+ + "\t"+ `"static_url":` +`""` +"," +"\n"+ + "\t"+ `"url":` +`""` +"," +"\n"+ + "\t"+ `"visible_in_picker":` +`true` +"" +"\n"+ + "}" +"\n", + }, + } + + for testNumber, test := range tests { + + actualBytes, err := test.Value.MarshalJSON() + if nil != err { + t.Errorf("For test #%d, did not expect to get an error but actually got one.", testNumber) + t.Logf("ERROR: (%T) %s", err, err) + t.Logf("VALUE: %#v", test.Value) + continue + } + + actual := string(actualBytes) + + var expected string + { + var buffer bytes.Buffer + + err := json.Compact(&buffer, []byte(test.Expected)) + if nil != err { + panic(err) + } + + expected = buffer.String() + } + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected.", testNumber) + t.Logf("EXPECTED:\n%s", expected) + t.Logf("ACTUAL:\n%s", actual) + t.Logf("EXPECTED: %q", expected) + t.Logf("ACTUAL: %q", actual) + t.Logf("VALUE: %#v", test.Value) + continue + } + + } +}