Add Listing/KarmaList to thing struct, tweak anonymous structs

Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
Vartan Benohanian 2020-09-01 22:35:28 -04:00
parent 5bb7a155de
commit ffcc906c07
12 changed files with 242 additions and 128 deletions

View file

@ -24,7 +24,7 @@ func run() (err error) {
return return
} }
post, _, err := client.Post.SubmitText(ctx, reddit.SubmitTextOptions{ post, _, err := client.Post.SubmitText(ctx, reddit.SubmitTextRequest{
Subreddit: "test", Subreddit: "test",
Title: "This is a title", Title: "This is a title",
Text: "This is some text", Text: "This is some text",
@ -35,7 +35,7 @@ func run() (err error) {
fmt.Printf("The text post is available at: %s\n", post.URL) fmt.Printf("The text post is available at: %s\n", post.URL)
post, _, err = client.Post.SubmitLink(ctx, reddit.SubmitLinkOptions{ post, _, err = client.Post.SubmitLink(ctx, reddit.SubmitLinkRequest{
Subreddit: "test", Subreddit: "test",
Title: "This is a title", Title: "This is a title",
URL: "http://example.com", URL: "http://example.com",

View file

@ -14,11 +14,6 @@ type AccountService struct {
client *Client client *Client
} }
type rootSubredditKarma struct {
Kind string `json:"kind,omitempty"`
Data []SubredditKarma `json:"data,omitempty"`
}
// SubredditKarma holds user karma data for the subreddit. // SubredditKarma holds user karma data for the subreddit.
type SubredditKarma struct { type SubredditKarma struct {
Subreddit string `json:"sr"` Subreddit string `json:"sr"`
@ -239,7 +234,7 @@ func (s *AccountService) Info(ctx context.Context) (*User, *Response, error) {
} }
// Karma returns a breakdown of your karma per subreddit. // Karma returns a breakdown of your karma per subreddit.
func (s *AccountService) Karma(ctx context.Context) ([]SubredditKarma, *Response, error) { func (s *AccountService) Karma(ctx context.Context) ([]*SubredditKarma, *Response, error) {
path := "api/v1/me/karma" path := "api/v1/me/karma"
req, err := s.client.NewRequest(http.MethodGet, path, nil) req, err := s.client.NewRequest(http.MethodGet, path, nil)
@ -247,13 +242,14 @@ func (s *AccountService) Karma(ctx context.Context) ([]SubredditKarma, *Response
return nil, nil, err return nil, nil, err
} }
root := new(rootSubredditKarma) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Data, resp, nil karma, _ := root.Karma()
return karma, resp, nil
} }
// Settings returns your account settings. // Settings returns your account settings.

View file

@ -21,7 +21,7 @@ var expectedInfo = &User{
NSFW: true, NSFW: true,
} }
var expectedKarma = []SubredditKarma{ var expectedKarma = []*SubredditKarma{
{Subreddit: "nba", PostKarma: 144, CommentKarma: 21999}, {Subreddit: "nba", PostKarma: 144, CommentKarma: 21999},
{Subreddit: "redditdev", PostKarma: 19, CommentKarma: 4}, {Subreddit: "redditdev", PostKarma: 19, CommentKarma: 4},
{Subreddit: "test", PostKarma: 1, CommentKarma: 0}, {Subreddit: "test", PostKarma: 1, CommentKarma: 0},

View file

@ -52,11 +52,12 @@ type CollectionCreateRequest struct {
func (s *CollectionService) Get(ctx context.Context, id string) (*Collection, *Response, error) { func (s *CollectionService) Get(ctx context.Context, id string) (*Collection, *Response, error) {
path := "api/v1/collections/collection" path := "api/v1/collections/collection"
type params struct { params := struct {
ID string `url:"collection_id"` ID string `url:"collection_id"`
IncludePosts bool `url:"include_links"` IncludePosts bool `url:"include_links"`
} }{id, false}
path, err := addOptions(path, params{id, false})
path, err := addOptions(path, params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -79,10 +80,11 @@ func (s *CollectionService) Get(ctx context.Context, id string) (*Collection, *R
func (s *CollectionService) FromSubreddit(ctx context.Context, id string) ([]*Collection, *Response, error) { func (s *CollectionService) FromSubreddit(ctx context.Context, id string) ([]*Collection, *Response, error) {
path := "api/v1/collections/subreddit_collections" path := "api/v1/collections/subreddit_collections"
type params struct { params := struct {
SubredditID string `url:"sr_fullname"` SubredditID string `url:"sr_fullname"`
} }{id}
path, err := addOptions(path, params{id})
path, err := addOptions(path, params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View file

@ -24,13 +24,14 @@ func (s *ListingsService) Get(ctx context.Context, ids ...string) ([]*Post, []*C
return nil, nil, nil, nil, err return nil, nil, nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, nil, nil, resp, err return nil, nil, nil, resp, err
} }
return root.Posts, root.Comments, root.Subreddits, resp, nil listing, _ := root.Listing()
return listing.Posts(), listing.Comments(), listing.Subreddits(), resp, nil
} }
// GetPosts returns posts from their full IDs. // GetPosts returns posts from their full IDs.
@ -42,11 +43,12 @@ func (s *ListingsService) GetPosts(ctx context.Context, ids ...string) ([]*Post,
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }

View file

@ -60,13 +60,14 @@ func (s *ModerationService) Actions(ctx context.Context, subreddit string, opts
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.ModActions, resp, nil listing, _ := root.Listing()
return listing.ModActions(), resp, nil
} }
// AcceptInvite accepts a pending invite to moderate the specified subreddit. // AcceptInvite accepts a pending invite to moderate the specified subreddit.
@ -175,13 +176,14 @@ func (s *ModerationService) Edited(ctx context.Context, subreddit string, opts *
return nil, nil, nil, err return nil, nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
return root.Posts, root.Comments, resp, nil listing, _ := root.Listing()
return listing.Posts(), listing.Comments(), resp, nil
} }
// IgnoreReports prevents reports on a post or comment from causing notifications. // IgnoreReports prevents reports on a post or comment from causing notifications.

View file

@ -33,8 +33,8 @@ type Submitted struct {
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
} }
// SubmitTextOptions are options used for text posts. // SubmitTextRequest are options used for text posts.
type SubmitTextOptions struct { type SubmitTextRequest struct {
Subreddit string `url:"sr,omitempty"` Subreddit string `url:"sr,omitempty"`
Title string `url:"title,omitempty"` Title string `url:"title,omitempty"`
Text string `url:"text,omitempty"` Text string `url:"text,omitempty"`
@ -47,8 +47,8 @@ type SubmitTextOptions struct {
Spoiler bool `url:"spoiler,omitempty"` Spoiler bool `url:"spoiler,omitempty"`
} }
// SubmitLinkOptions are options used for link posts. // SubmitLinkRequest are options used for link posts.
type SubmitLinkOptions struct { type SubmitLinkRequest struct {
Subreddit string `url:"sr,omitempty"` Subreddit string `url:"sr,omitempty"`
Title string `url:"title,omitempty"` Title string `url:"title,omitempty"`
URL string `url:"url,omitempty"` URL string `url:"url,omitempty"`
@ -96,17 +96,20 @@ func (s *PostService) Duplicates(ctx context.Context, id string, opts *ListDupli
return nil, nil, nil, err return nil, nil, nil, err
} }
var root [2]listing var root [2]thing
resp, err := s.client.Do(ctx, req, &root) resp, err := s.client.Do(ctx, req, &root)
if err != nil { if err != nil {
return nil, nil, resp, err return nil, nil, resp, err
} }
post := root[0].Posts[0] listing1, _ := root[0].Listing()
duplicates := root[1].Posts listing2, _ := root[1].Listing()
resp.After = root[1].after post := listing1.Posts()[0]
resp.Before = root[1].after duplicates := listing2.Posts()
resp.After = listing2.After()
resp.Before = listing2.Before()
return post, duplicates, resp, nil return post, duplicates, resp, nil
} }
@ -135,21 +138,21 @@ func (s *PostService) submit(ctx context.Context, v interface{}) (*Submitted, *R
} }
// SubmitText submits a text post. // SubmitText submits a text post.
func (s *PostService) SubmitText(ctx context.Context, opts SubmitTextOptions) (*Submitted, *Response, error) { func (s *PostService) SubmitText(ctx context.Context, opts SubmitTextRequest) (*Submitted, *Response, error) {
type submit struct { form := struct {
SubmitTextOptions SubmitTextRequest
Kind string `url:"kind,omitempty"` Kind string `url:"kind,omitempty"`
} }{opts, "self"}
return s.submit(ctx, &submit{opts, "self"}) return s.submit(ctx, form)
} }
// SubmitLink submits a link post. // SubmitLink submits a link post.
func (s *PostService) SubmitLink(ctx context.Context, opts SubmitLinkOptions) (*Submitted, *Response, error) { func (s *PostService) SubmitLink(ctx context.Context, opts SubmitLinkRequest) (*Submitted, *Response, error) {
type submit struct { form := struct {
SubmitLinkOptions SubmitLinkRequest
Kind string `url:"kind,omitempty"` Kind string `url:"kind,omitempty"`
} }{opts, "link"}
return s.submit(ctx, &submit{opts, "link"}) return s.submit(ctx, form)
} }
// Edit a post. // Edit a post.

View file

@ -281,7 +281,7 @@ func TestPostService_SubmitText(t *testing.T) {
fmt.Fprint(w, blob) fmt.Fprint(w, blob)
}) })
submittedPost, _, err := client.Post.SubmitText(ctx, SubmitTextOptions{ submittedPost, _, err := client.Post.SubmitText(ctx, SubmitTextRequest{
Subreddit: "test", Subreddit: "test",
Title: "Test Title", Title: "Test Title",
Text: "Test Text", Text: "Test Text",
@ -318,7 +318,7 @@ func TestPostService_SubmitLink(t *testing.T) {
fmt.Fprint(w, blob) fmt.Fprint(w, blob)
}) })
submittedPost, _, err := client.Post.SubmitLink(ctx, SubmitLinkOptions{ submittedPost, _, err := client.Post.SubmitLink(ctx, SubmitLinkRequest{
Subreddit: "test", Subreddit: "test",
Title: "Test Title", Title: "Test Title",
URL: "https://www.example.com", URL: "https://www.example.com",

View file

@ -60,13 +60,14 @@ func (s *SubredditService) getPosts(ctx context.Context, sort string, subreddit
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }
// HotPosts returns the hottest posts from the specified subreddit. // HotPosts returns the hottest posts from the specified subreddit.
@ -269,10 +270,11 @@ func (s *SubredditService) Search(ctx context.Context, query string, opts *ListS
return nil, nil, err return nil, nil, err
} }
type params struct { params := struct {
Query string `url:"q"` Query string `url:"q"`
} }{query}
path, err = addOptions(path, params{query})
path, err = addOptions(path, params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -282,13 +284,14 @@ func (s *SubredditService) Search(ctx context.Context, query string, opts *ListS
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Subreddits, resp, nil listing, _ := root.Listing()
return listing.Subreddits(), resp, nil
} }
// SearchNames searches for subreddits with names beginning with the query provided. // SearchNames searches for subreddits with names beginning with the query provided.
@ -323,13 +326,14 @@ func (s *SubredditService) SearchPosts(ctx context.Context, query string, subred
return nil, nil, err return nil, nil, err
} }
type params struct { notAll := !strings.EqualFold(subreddit, "all")
params := struct {
Query string `url:"q"` Query string `url:"q"`
RestrictSubreddits bool `url:"restrict_sr,omitempty"` RestrictSubreddits bool `url:"restrict_sr,omitempty"`
} }{query, notAll}
notAll := !strings.EqualFold(subreddit, "all") path, err = addOptions(path, params)
path, err = addOptions(path, params{query, notAll})
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -339,13 +343,14 @@ func (s *SubredditService) SearchPosts(ctx context.Context, query string, subred
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }
func (s *SubredditService) getSubreddits(ctx context.Context, path string, opts *ListSubredditOptions) ([]*Subreddit, *Response, error) { func (s *SubredditService) getSubreddits(ctx context.Context, path string, opts *ListSubredditOptions) ([]*Subreddit, *Response, error) {
@ -359,24 +364,25 @@ func (s *SubredditService) getSubreddits(ctx context.Context, path string, opts
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Subreddits, resp, nil listing, _ := root.Listing()
return listing.Subreddits(), resp, nil
} }
// getSticky returns one of the 2 stickied posts of the subreddit (if they exist). // getSticky returns one of the 2 stickied posts of the subreddit (if they exist).
// Num should be equal to 1 or 2, depending on which one you want. // Num should be equal to 1 or 2, depending on which one you want.
func (s *SubredditService) getSticky(ctx context.Context, subreddit string, num int) (*PostAndComments, *Response, error) { func (s *SubredditService) getSticky(ctx context.Context, subreddit string, num int) (*PostAndComments, *Response, error) {
type params struct { params := struct {
Num int `url:"num"` Num int `url:"num"`
} }{num}
path := fmt.Sprintf("r/%s/about/sticky", subreddit) path := fmt.Sprintf("r/%s/about/sticky", subreddit)
path, err := addOptions(path, params{num}) path, err := addOptions(path, params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -402,12 +408,12 @@ func (s *SubredditService) random(ctx context.Context, nsfw bool) (*Subreddit, *
path = "r/randnsfw" path = "r/randnsfw"
} }
type params struct { params := struct {
ExpandSubreddit bool `url:"sr_detail"` ExpandSubreddit bool `url:"sr_detail"`
Limit int `url:"limit,omitempty"` Limit int `url:"limit,omitempty"`
} }{true, 1}
path, err := addOptions(path, params{true, 1}) path, err := addOptions(path, params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View file

@ -21,6 +21,11 @@ const (
kindMulti = "LabeledMulti" kindMulti = "LabeledMulti"
) )
type anchor interface {
After() string
Before() string
}
// thing is an entity on Reddit. // thing is an entity on Reddit.
// Its kind reprsents what it is and what is stored in the Data field. // Its kind reprsents what it is and what is stored in the Data field.
// e.g. t1 = comment, t2 = user, t3 = post, etc. // e.g. t1 = comment, t2 = user, t3 = post, etc.
@ -29,6 +34,28 @@ type thing struct {
Data interface{} `json:"data"` Data interface{} `json:"data"`
} }
func (t *thing) After() string {
if t == nil {
return ""
}
a, ok := t.Data.(anchor)
if !ok {
return ""
}
return a.After()
}
func (t *thing) Before() string {
if t == nil {
return ""
}
a, ok := t.Data.(anchor)
if !ok {
return ""
}
return a.Before()
}
// UnmarshalJSON implements the json.Unmarshaler interface. // UnmarshalJSON implements the json.Unmarshaler interface.
func (t *thing) UnmarshalJSON(b []byte) error { func (t *thing) UnmarshalJSON(b []byte) error {
root := new(struct { root := new(struct {
@ -45,6 +72,8 @@ func (t *thing) UnmarshalJSON(b []byte) error {
var v interface{} var v interface{}
switch t.Kind { switch t.Kind {
case kindListing:
v = new(listing)
case kindComment: case kindComment:
v = new(Comment) v = new(Comment)
case kindMore: case kindMore:
@ -63,6 +92,8 @@ func (t *thing) UnmarshalJSON(b []byte) error {
v = new(Trophy) v = new(Trophy)
case kindTrophyList: case kindTrophyList:
v = new(trophyList) v = new(trophyList)
case kindKarmaList:
v = new([]*SubredditKarma)
default: default:
return fmt.Errorf("unrecognized kind: %q", t.Kind) return fmt.Errorf("unrecognized kind: %q", t.Kind)
} }
@ -76,6 +107,11 @@ func (t *thing) UnmarshalJSON(b []byte) error {
return nil return nil
} }
func (t *thing) Listing() (v *listing, ok bool) {
v, ok = t.Data.(*listing)
return
}
func (t *thing) Comment() (v *Comment, ok bool) { func (t *thing) Comment() (v *Comment, ok bool) {
v, ok = t.Data.(*Comment) v, ok = t.Data.(*Comment)
return return
@ -118,18 +154,24 @@ func (t *thing) Trophy() (v *Trophy, ok bool) {
func (t *thing) TrophyList() ([]*Trophy, bool) { func (t *thing) TrophyList() ([]*Trophy, bool) {
v, ok := t.Data.(*trophyList) v, ok := t.Data.(*trophyList)
if !ok {
return nil, ok
}
return *v, ok return *v, ok
} }
type anchor interface { func (t *thing) Karma() ([]*SubredditKarma, bool) {
After() string v, ok := t.Data.(*[]*SubredditKarma)
Before() string if !ok {
return nil, ok
}
return *v, ok
} }
// listing is a list of things coming from the Reddit API. // listing is a list of things coming from the Reddit API.
// It also contains the after/before anchors useful for subsequent requests. // It also contains the after/before anchors useful for subsequent requests.
type listing struct { type listing struct {
things things things
after string after string
before string before string
} }
@ -145,11 +187,9 @@ func (l *listing) Before() string {
// UnmarshalJSON implements the json.Unmarshaler interface. // UnmarshalJSON implements the json.Unmarshaler interface.
func (l *listing) UnmarshalJSON(b []byte) error { func (l *listing) UnmarshalJSON(b []byte) error {
root := new(struct { root := new(struct {
Data struct {
Things things `json:"children"` Things things `json:"children"`
After string `json:"after"` After string `json:"after"`
Before string `json:"before"` Before string `json:"before"`
} `json:"data"`
}) })
err := json.Unmarshal(b, root) err := json.Unmarshal(b, root)
@ -157,13 +197,62 @@ func (l *listing) UnmarshalJSON(b []byte) error {
return err return err
} }
l.things = root.Data.Things l.things = root.Things
l.after = root.Data.After l.after = root.After
l.before = root.Data.Before l.before = root.Before
return nil return nil
} }
func (l *listing) Comments() []*Comment {
if l == nil {
return nil
}
return l.things.Comments
}
func (l *listing) Mores() []*More {
if l == nil {
return nil
}
return l.things.Mores
}
func (l *listing) Users() []*User {
if l == nil {
return nil
}
return l.things.Users
}
func (l *listing) Posts() []*Post {
if l == nil {
return nil
}
return l.things.Posts
}
func (l *listing) Subreddits() []*Subreddit {
if l == nil {
return nil
}
return l.things.Subreddits
}
func (l *listing) ModActions() []*ModAction {
if l == nil {
return nil
}
return l.things.ModActions
}
func (l *listing) Multis() []*Multi {
if l == nil {
return nil
}
return l.things.Multis
}
type things struct { type things struct {
Comments []*Comment Comments []*Comment
Mores []*More Mores []*More
@ -334,15 +423,17 @@ func (r *Replies) UnmarshalJSON(data []byte) error {
return nil return nil
} }
root := new(listing) root := new(thing)
err := json.Unmarshal(data, root) err := json.Unmarshal(data, root)
if err != nil { if err != nil {
return err return err
} }
r.Comments = root.Comments listing, _ := root.Listing()
if len(root.Mores) > 0 {
r.More = root.Mores[0] r.Comments = listing.Comments()
if len(listing.Mores()) > 0 {
r.More = listing.Mores()[0]
} }
return nil return nil
@ -438,17 +529,20 @@ type PostAndComments struct {
// The 1st one contains the single post in its children array // The 1st one contains the single post in its children array
// The 2nd one contains the comments to the post // The 2nd one contains the comments to the post
func (pc *PostAndComments) UnmarshalJSON(data []byte) error { func (pc *PostAndComments) UnmarshalJSON(data []byte) error {
var l [2]listing var root [2]thing
err := json.Unmarshal(data, &l) err := json.Unmarshal(data, &root)
if err != nil { if err != nil {
return err return err
} }
pc.Post = l[0].Posts[0] listing1, _ := root[0].Listing()
pc.Comments = l[1].Comments listing2, _ := root[1].Listing()
if len(l[1].Mores) > 0 {
pc.More = l[1].Mores[0] pc.Post = listing1.Posts()[0]
pc.Comments = listing2.Comments()
if len(listing2.Mores()) > 0 {
pc.More = listing2.Mores()[0]
} }
return nil return nil

View file

@ -79,12 +79,12 @@ func (s *UserService) Get(ctx context.Context, username string) (*User, *Respons
// GetMultipleByID returns multiple users from their full IDs. // GetMultipleByID returns multiple users from their full IDs.
// The response body is a map where the keys are the IDs (if they exist), and the value is the user. // The response body is a map where the keys are the IDs (if they exist), and the value is the user.
func (s *UserService) GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserSummary, *Response, error) { func (s *UserService) GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserSummary, *Response, error) {
type params struct { params := struct {
IDs []string `url:"ids,omitempty,comma"` IDs []string `url:"ids,omitempty,comma"`
} }{ids}
path := "api/user_data_by_account_ids" path := "api/user_data_by_account_ids"
path, err := addOptions(path, params{ids}) path, err := addOptions(path, params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -105,12 +105,12 @@ func (s *UserService) GetMultipleByID(ctx context.Context, ids ...string) (map[s
// UsernameAvailable checks whether a username is available for registration. // UsernameAvailable checks whether a username is available for registration.
func (s *UserService) UsernameAvailable(ctx context.Context, username string) (bool, *Response, error) { func (s *UserService) UsernameAvailable(ctx context.Context, username string) (bool, *Response, error) {
type params struct { params := struct {
User string `url:"user"` User string `url:"user"`
} }{username}
path := "api/username_available" path := "api/username_available"
path, err := addOptions(path, params{username}) path, err := addOptions(path, params)
if err != nil { if err != nil {
return false, nil, err return false, nil, err
} }
@ -147,13 +147,14 @@ func (s *UserService) OverviewOf(ctx context.Context, username string, opts *Lis
return nil, nil, nil, err return nil, nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, nil, resp, err return nil, nil, resp, err
} }
return root.Posts, root.Comments, resp, nil listing, _ := root.Listing()
return listing.Posts(), listing.Comments(), resp, nil
} }
// Posts returns a list of your posts. // Posts returns a list of your posts.
@ -174,13 +175,14 @@ func (s *UserService) PostsOf(ctx context.Context, username string, opts *ListUs
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }
// Comments returns a list of your comments. // Comments returns a list of your comments.
@ -201,13 +203,14 @@ func (s *UserService) CommentsOf(ctx context.Context, username string, opts *Lis
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Comments, resp, nil listing, _ := root.Listing()
return listing.Comments(), resp, nil
} }
// Saved returns a list of the user's saved posts and comments. // Saved returns a list of the user's saved posts and comments.
@ -223,13 +226,14 @@ func (s *UserService) Saved(ctx context.Context, opts *ListUserOverviewOptions)
return nil, nil, nil, err return nil, nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, nil, resp, err return nil, nil, resp, err
} }
return root.Posts, root.Comments, resp, nil listing, _ := root.Listing()
return listing.Posts(), listing.Comments(), resp, nil
} }
// Upvoted returns a list of your upvoted posts. // Upvoted returns a list of your upvoted posts.
@ -251,13 +255,14 @@ func (s *UserService) UpvotedOf(ctx context.Context, username string, opts *List
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }
// Downvoted returns a list of your downvoted posts. // Downvoted returns a list of your downvoted posts.
@ -279,13 +284,14 @@ func (s *UserService) DownvotedOf(ctx context.Context, username string, opts *Li
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }
// Hidden returns a list of the user's hidden posts. // Hidden returns a list of the user's hidden posts.
@ -301,13 +307,14 @@ func (s *UserService) Hidden(ctx context.Context, opts *ListUserOverviewOptions)
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }
// Gilded returns a list of the user's gilded posts. // Gilded returns a list of the user's gilded posts.
@ -323,13 +330,14 @@ func (s *UserService) Gilded(ctx context.Context, opts *ListUserOverviewOptions)
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Posts, resp, nil listing, _ := root.Listing()
return listing.Posts(), resp, nil
} }
// GetFriendship returns relationship details with the specified user. // GetFriendship returns relationship details with the specified user.
@ -353,13 +361,11 @@ func (s *UserService) GetFriendship(ctx context.Context, username string) (*Rela
// Friend a user. // Friend a user.
func (s *UserService) Friend(ctx context.Context, username string) (*Relationship, *Response, error) { func (s *UserService) Friend(ctx context.Context, username string) (*Relationship, *Response, error) {
type request struct { body := struct {
Username string `json:"name"` Username string `json:"name"`
} }{username}
path := fmt.Sprintf("api/v1/me/friends/%s", username) path := fmt.Sprintf("api/v1/me/friends/%s", username)
body := request{username}
req, err := s.client.NewRequest(http.MethodPut, path, body) req, err := s.client.NewRequest(http.MethodPut, path, body)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -507,13 +513,14 @@ func (s *UserService) Popular(ctx context.Context, opts *ListOptions) ([]*Subred
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Subreddits, resp, nil listing, _ := root.Listing()
return listing.Subreddits(), resp, nil
} }
// New gets the most recently created user subreddits. // New gets the most recently created user subreddits.
@ -529,13 +536,14 @@ func (s *UserService) New(ctx context.Context, opts *ListUserOverviewOptions) ([
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Subreddits, resp, nil listing, _ := root.Listing()
return listing.Subreddits(), resp, nil
} }
// Search for users. // Search for users.
@ -547,10 +555,11 @@ func (s *UserService) Search(ctx context.Context, query string, opts *ListOption
return nil, nil, err return nil, nil, err
} }
type params struct { params := struct {
Query string `url:"q"` Query string `url:"q"`
} }{query}
path, err = addOptions(path, params{query})
path, err = addOptions(path, params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -560,11 +569,12 @@ func (s *UserService) Search(ctx context.Context, query string, opts *ListOption
return nil, nil, err return nil, nil, err
} }
root := new(listing) root := new(thing)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return root.Users, resp, nil listing, _ := root.Listing()
return listing.Users(), resp, nil
} }

View file

@ -735,14 +735,13 @@ func TestUserService_Friend(t *testing.T) {
mux.HandleFunc("/api/v1/me/friends/test123", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/api/v1/me/friends/test123", func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPut, r.Method) require.Equal(t, http.MethodPut, r.Method)
type request struct { var request struct {
Username string `json:"name"` Username string `json:"name"`
} }
var req request err := json.NewDecoder(r.Body).Decode(&request)
err := json.NewDecoder(r.Body).Decode(&req)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "test123", req.Username) require.Equal(t, "test123", request.Username)
fmt.Fprint(w, blob) fmt.Fprint(w, blob)
}) })