Rename structs, move them to a separate file

Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
Vartan Benohanian 2020-05-03 19:17:39 -04:00
parent 9e7cb10526
commit c897c14b23
6 changed files with 343 additions and 362 deletions

View file

@ -25,15 +25,6 @@ type CommentServiceOp struct {
var _ CommentService = &CommentServiceOp{} var _ CommentService = &CommentServiceOp{}
// CommentList holds information about a list of comments
// The after and before fields help decide the anchor point for a subsequent
// call that returns a list
type CommentList struct {
Comments []Comment `json:"comments,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
}
func (s *CommentServiceOp) isCommentID(id string) bool { func (s *CommentServiceOp) isCommentID(id string) bool {
return strings.HasPrefix(id, kindComment+"_") return strings.HasPrefix(id, kindComment+"_")
} }

230
geddit.go
View file

@ -380,233 +380,3 @@ func addOptions(s string, opt interface{}) (string, error) {
origURL.RawQuery = origValues.Encode() origURL.RawQuery = origValues.Encode()
return origURL.String(), nil return origURL.String(), nil
} }
type root struct {
Kind string `json:"kind,omitempty"`
Data interface{} `json:"data,omitempty"`
}
type rootListing struct {
Kind string `json:"kind,omitempty"`
Data *Listing `json:"data"`
}
// Listing holds things coming from the Reddit API
// It also contains the after/before anchors useful for subsequent requests
type Listing struct {
Things Things `json:"children"`
After string `json:"after"`
Before string `json:"before"`
}
// Things are stuff!
type Things struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
// todo: add the other kinds of things
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (l *Things) UnmarshalJSON(b []byte) error {
var children []map[string]interface{}
if err := json.Unmarshal(b, &children); err != nil {
return err
}
for _, child := range children {
byteValue, _ := json.Marshal(child)
switch child["kind"] {
case kindComment:
root := new(commentRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Comments = append(l.Comments, *root.Data)
}
case kindAccount:
case kindLink:
root := new(linkRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Links = append(l.Links, *root.Data)
}
case kindMessage:
case kindSubreddit:
root := new(subredditRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Subreddits = append(l.Subreddits, *root.Data)
}
case kindAward:
}
}
return nil
}
const (
kindListing string = "Listing"
kindComment string = "t1"
kindAccount string = "t2"
kindLink string = "t3"
kindMessage string = "t4"
kindSubreddit string = "t5"
kindAward string = "t6"
)
type commentRoot struct {
Kind string `json:"kind,omitempty"`
Data *Comment `json:"data,omitempty"`
}
type linkRoot struct {
Kind string `json:"kind,omitempty"`
Data *Link `json:"data,omitempty"`
}
type subredditRoot struct {
Kind string `json:"kind,omitempty"`
Data *Subreddit `json:"data,omitempty"`
}
// Comment is a comment posted by a user
type Comment struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
ParentID string `json:"parent_id,omitempty"`
Permalink string `json:"permalink,omitempty"`
Body string `json:"body,omitempty"`
Author string `json:"author,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorFlairText string `json:"author_flair_text,omitempty"`
AuthorFlairID string `json:"author_flair_template_id,omitempty"`
Subreddit string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
SubredditID string `json:"subreddit_id,omitempty"`
Score int `json:"score"`
Controversiality int `json:"controversiality"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
LinkID string `json:"link_id,omitempty"`
// These don't appear when submitting a comment
LinkTitle string `json:"link_title,omitempty"`
LinkPermalink string `json:"link_permalink,omitempty"`
LinkAuthor string `json:"link_author,omitempty"`
LinkNumComments int `json:"num_comments"`
IsSubmitter bool `json:"is_submitter"`
ScoreHidden bool `json:"score_hidden"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
Locked bool `json:"locked"`
CanGild bool `json:"can_gild"`
NSFW bool `json:"over_18"`
// If a comment has no replies, its "replies" value is "",
// which the unmarshaler doesn't like
// So we capture this varying field in RepliesRaw, and then
// fill it in Replies
RepliesRaw json.RawMessage `json:"replies,omitempty"`
Replies []commentRoot `json:"-"`
}
// Link is a submitted post on Reddit
type Link struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
Permalink string `json:"permalink,omitempty"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Body string `json:"selftext,omitempty"`
Score int `json:"score"`
NumberOfComments int `json:"num_comments"`
SubredditID string `json:"subreddit_id,omitempty"`
SubredditName string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorName string `json:"author,omitempty"`
Spoiler bool `json:"spoiler"`
Locked bool `json:"locked"`
NSFW bool `json:"over_18"`
IsSelfPost bool `json:"is_self"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
}
// Subreddit holds information about a subreddit
type Subreddit struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
URL string `json:"url,omitempty"`
Name string `json:"display_name,omitempty"`
NamePrefixed string `json:"display_name_prefixed,omitempty"`
Title string `json:"title,omitempty"`
PublicDescription string `json:"public_description,omitempty"`
Type string `json:"subreddit_type,omitempty"`
SuggestedCommentSort string `json:"suggested_comment_sort,omitempty"`
Subscribers int `json:"subscribers"`
ActiveUserCount *int `json:"active_user_count,omitempty"`
NSFW bool `json:"over18"`
UserIsMod bool `json:"user_is_moderator"`
}
func (rl *rootListing) getAfter() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.After
}
func (rl *rootListing) getBefore() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.Before
}
func (rl *rootListing) getComments() *CommentList {
if rl == nil || rl.Data == nil {
return nil
}
return &CommentList{
Comments: rl.Data.Things.Comments,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getLinks() *LinkList {
if rl == nil || rl.Data == nil {
return nil
}
return &LinkList{
Links: rl.Data.Things.Links,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getSubreddits() *SubredditList {
if rl == nil || rl.Data == nil {
return nil
}
return &SubredditList{
Subreddits: rl.Data.Things.Subreddits,
After: rl.Data.After,
Before: rl.Data.Before,
}
}

View file

@ -18,30 +18,6 @@ type ListingsServiceOp struct {
var _ ListingsService = &ListingsServiceOp{} var _ ListingsService = &ListingsServiceOp{}
type listingRoot struct {
Kind string `json:"kind,omitempty"`
Data *struct {
Dist int `json:"dist"`
Children []map[string]interface{} `json:"children,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
} `json:"data,omitempty"`
}
// Listing holds various types of things that all come from the Reddit API
// type Listing struct {
// Links []*Submission `json:"links,omitempty"`
// Comments []*Comment `json:"comments,omitempty"`
// Subreddits []*Subreddit `json:"subreddits,omitempty"`
// }
// CommentsLinksSubreddits holds comments, links, and subreddits
type CommentsLinksSubreddits struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
}
// Get gets a list of things based on their IDs // Get gets a list of things based on their IDs
// Only links, comments, and subreddits are allowed // Only links, comments, and subreddits are allowed
func (s *ListingsServiceOp) Get(ctx context.Context, ids ...string) (*CommentsLinksSubreddits, *Response, error) { func (s *ListingsServiceOp) Get(ctx context.Context, ids ...string) (*CommentsLinksSubreddits, *Response, error) {

View file

@ -15,22 +15,22 @@ import (
type SubredditService interface { type SubredditService interface {
GetByName(ctx context.Context, name string) (*Subreddit, *Response, error) GetByName(ctx context.Context, name string) (*Subreddit, *Response, error)
GetPopular(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetPopular(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetNew(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetNew(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetGold(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetGold(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetDefault(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetDefault(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetMineWhereContributor(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetMineWhereContributor(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetHotLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) GetHotLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetBestLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) GetBestLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error)
// GetSticky1(ctx context.Context, name string) (interface{}, *Response, error) // GetSticky1(ctx context.Context, name string) (interface{}, *Response, error)
// GetSticky2(ctx context.Context, name string) (interface{}, *Response, error) // GetSticky2(ctx context.Context, name string) (interface{}, *Response, error)
@ -50,25 +50,6 @@ type SubredditServiceOp struct {
var _ SubredditService = &SubredditServiceOp{} var _ SubredditService = &SubredditServiceOp{}
// SubredditList holds information about a list of subreddits
// The after and before fields help decide the anchor point for a subsequent
// call that returns a list
type SubredditList struct {
Subreddits []Subreddit `json:"subreddits,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
}
// LinkList holds information about a list of links
// The after and before fields help decide the anchor point for a subsequent
// call that returns a list
// Note: not to be confused with linked lists
type LinkList struct {
Links []Link `json:"submissions,omitempty"`
After string `json:"after,omitempty"`
Before string `json:"before,omitempty"`
}
// GetByName gets a subreddit by name // GetByName gets a subreddit by name
func (s *SubredditServiceOp) GetByName(ctx context.Context, name string) (*Subreddit, *Response, error) { func (s *SubredditServiceOp) GetByName(ctx context.Context, name string) (*Subreddit, *Response, error) {
if name == "" { if name == "" {
@ -91,42 +72,42 @@ func (s *SubredditServiceOp) GetByName(ctx context.Context, name string) (*Subre
} }
// GetPopular returns popular subreddits // GetPopular returns popular subreddits
func (s *SubredditServiceOp) GetPopular(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetPopular(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/popular", opts) return s.getSubreddits(ctx, "subreddits/popular", opts)
} }
// GetNew returns new subreddits // GetNew returns new subreddits
func (s *SubredditServiceOp) GetNew(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetNew(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/new", opts) return s.getSubreddits(ctx, "subreddits/new", opts)
} }
// GetGold returns gold subreddits // GetGold returns gold subreddits
func (s *SubredditServiceOp) GetGold(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetGold(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/gold", opts) return s.getSubreddits(ctx, "subreddits/gold", opts)
} }
// GetDefault returns default subreddits // GetDefault returns default subreddits
func (s *SubredditServiceOp) GetDefault(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetDefault(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/default", opts) return s.getSubreddits(ctx, "subreddits/default", opts)
} }
// GetMineWhereSubscriber returns the list of subreddits the client is subscribed to // GetMineWhereSubscriber returns the list of subreddits the client is subscribed to
func (s *SubredditServiceOp) GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetMineWhereSubscriber(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/subscriber", opts) return s.getSubreddits(ctx, "subreddits/mine/subscriber", opts)
} }
// GetMineWhereContributor returns the list of subreddits the client is a contributor to // GetMineWhereContributor returns the list of subreddits the client is a contributor to
func (s *SubredditServiceOp) GetMineWhereContributor(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetMineWhereContributor(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts) return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
} }
// GetMineWhereModerator returns the list of subreddits the client is a moderator in // GetMineWhereModerator returns the list of subreddits the client is a moderator in
func (s *SubredditServiceOp) GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetMineWhereModerator(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts) return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
} }
// GetMineWhereStreams returns the list of subreddits the client is subscribed to and has hosted videos in // GetMineWhereStreams returns the list of subreddits the client is subscribed to and has hosted videos in
func (s *SubredditServiceOp) GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) GetMineWhereStreams(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) {
return s.getSubreddits(ctx, "subreddits/mine/contributor", opts) return s.getSubreddits(ctx, "subreddits/mine/contributor", opts)
} }
@ -154,7 +135,7 @@ var sorts = [...]string{
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to // If no subreddit names are provided, then it runs the search against all those the client is subscribed to
// IMPORTANT: for subreddits, this will include the stickied posts (if any) // IMPORTANT: for subreddits, this will include the stickied posts (if any)
// PLUS the number of posts from the limit parameter (which is 25 by default) // PLUS the number of posts from the limit parameter (which is 25 by default)
func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) { func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortHot, opts, names...) return s.getLinks(ctx, sortHot, opts, names...)
} }
@ -162,31 +143,31 @@ func (s *SubredditServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions,
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to // If no subreddit names are provided, then it runs the search against all those the client is subscribed to
// IMPORTANT: for subreddits, this will include the stickied posts (if any) // IMPORTANT: for subreddits, this will include the stickied posts (if any)
// PLUS the number of posts from the limit parameter (which is 25 by default) // PLUS the number of posts from the limit parameter (which is 25 by default)
func (s *SubredditServiceOp) GetBestLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) { func (s *SubredditServiceOp) GetBestLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortBest, opts, names...) return s.getLinks(ctx, sortBest, opts, names...)
} }
// GetNewLinks returns the new links // GetNewLinks returns the new links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to // If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) { func (s *SubredditServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortNew, opts, names...) return s.getLinks(ctx, sortNew, opts, names...)
} }
// GetRisingLinks returns the rising links // GetRisingLinks returns the rising links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to // If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) { func (s *SubredditServiceOp) GetRisingLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortRising, opts, names...) return s.getLinks(ctx, sortRising, opts, names...)
} }
// GetControversialLinks returns the controversial links // GetControversialLinks returns the controversial links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to // If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) { func (s *SubredditServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortControversial, opts, names...) return s.getLinks(ctx, sortControversial, opts, names...)
} }
// GetTopLinks returns the top links // GetTopLinks returns the top links
// If no subreddit names are provided, then it runs the search against all those the client is subscribed to // If no subreddit names are provided, then it runs the search against all those the client is subscribed to
func (s *SubredditServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*LinkList, *Response, error) { func (s *SubredditServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions, names ...string) (*Links, *Response, error) {
return s.getLinks(ctx, sortTop, opts, names...) return s.getLinks(ctx, sortTop, opts, names...)
} }
@ -258,7 +239,7 @@ func (s *SubredditServiceOp) handleSubscription(ctx context.Context, form url.Va
return resp, nil return resp, nil
} }
func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opts *ListOptions) (*SubredditList, *Response, error) { func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opts *ListOptions) (*Subreddits, *Response, error) {
path, err := addOptions(path, opts) path, err := addOptions(path, opts)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -275,7 +256,7 @@ func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opt
return nil, resp, err return nil, resp, err
} }
l := new(SubredditList) l := new(Subreddits)
if root.Data != nil { if root.Data != nil {
l.Subreddits = root.Data.Things.Subreddits l.Subreddits = root.Data.Things.Subreddits
@ -286,7 +267,7 @@ func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opt
return l, resp, nil return l, resp, nil
} }
func (s *SubredditServiceOp) getLinks(ctx context.Context, sort sort, opts *ListOptions, names ...string) (*LinkList, *Response, error) { func (s *SubredditServiceOp) getLinks(ctx context.Context, sort sort, opts *ListOptions, names ...string) (*Links, *Response, error) {
path := sorts[sort] path := sorts[sort]
if len(names) > 0 { if len(names) > 0 {
path = fmt.Sprintf("r/%s/%s", strings.Join(names, "+"), sorts[sort]) path = fmt.Sprintf("r/%s/%s", strings.Join(names, "+"), sorts[sort])
@ -308,7 +289,7 @@ func (s *SubredditServiceOp) getLinks(ctx context.Context, sort sort, opts *List
return nil, resp, err return nil, resp, err
} }
l := new(LinkList) l := new(Links)
if root.Data != nil { if root.Data != nil {
l.Links = root.Data.Things.Links l.Links = root.Data.Things.Links

271
things.go Normal file
View file

@ -0,0 +1,271 @@
package geddit
import "encoding/json"
const (
kindComment = "t1"
kindAccount = "t2"
kindLink = "t3"
kindMessage = "t4"
kindSubreddit = "t5"
kindAward = "t6"
kindListing = "Listing"
kindUserList = "UserList"
kindMode = "more"
)
type root struct {
Kind string `json:"kind,omitempty"`
Data interface{} `json:"data,omitempty"`
}
type rootListing struct {
Kind string `json:"kind,omitempty"`
Data *Listing `json:"data"`
}
// Listing holds things coming from the Reddit API
// It also contains the after/before anchors useful for subsequent requests
type Listing struct {
Things Things `json:"children"`
After string `json:"after"`
Before string `json:"before"`
}
// Things are stuff!
type Things struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
// todo: add the other kinds of things
}
type commentRoot struct {
Kind string `json:"kind,omitempty"`
Data *Comment `json:"data,omitempty"`
}
type linkRoot struct {
Kind string `json:"kind,omitempty"`
Data *Link `json:"data,omitempty"`
}
type subredditRoot struct {
Kind string `json:"kind,omitempty"`
Data *Subreddit `json:"data,omitempty"`
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (l *Things) UnmarshalJSON(b []byte) error {
var children []map[string]interface{}
if err := json.Unmarshal(b, &children); err != nil {
return err
}
for _, child := range children {
byteValue, _ := json.Marshal(child)
switch child["kind"] {
case kindComment:
root := new(commentRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Comments = append(l.Comments, *root.Data)
}
case kindAccount:
case kindLink:
root := new(linkRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Links = append(l.Links, *root.Data)
}
case kindMessage:
case kindSubreddit:
root := new(subredditRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Subreddits = append(l.Subreddits, *root.Data)
}
case kindAward:
}
}
return nil
}
// Comment is a comment posted by a user
type Comment struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
ParentID string `json:"parent_id,omitempty"`
Permalink string `json:"permalink,omitempty"`
Body string `json:"body,omitempty"`
Author string `json:"author,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorFlairText string `json:"author_flair_text,omitempty"`
AuthorFlairID string `json:"author_flair_template_id,omitempty"`
Subreddit string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
SubredditID string `json:"subreddit_id,omitempty"`
Score int `json:"score"`
Controversiality int `json:"controversiality"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
LinkID string `json:"link_id,omitempty"`
// These don't appear when submitting a comment
LinkTitle string `json:"link_title,omitempty"`
LinkPermalink string `json:"link_permalink,omitempty"`
LinkAuthor string `json:"link_author,omitempty"`
LinkNumComments int `json:"num_comments"`
IsSubmitter bool `json:"is_submitter"`
ScoreHidden bool `json:"score_hidden"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
Locked bool `json:"locked"`
CanGild bool `json:"can_gild"`
NSFW bool `json:"over_18"`
// If a comment has no replies, its "replies" value is "",
// which the unmarshaler doesn't like
// So we capture this varying field in RepliesRaw, and then
// fill it in Replies
RepliesRaw json.RawMessage `json:"replies,omitempty"`
Replies []commentRoot `json:"-"`
}
// Link is a submitted post on Reddit
type Link struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
Edited *Timestamp `json:"edited,omitempty"`
Permalink string `json:"permalink,omitempty"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Body string `json:"selftext,omitempty"`
Score int `json:"score"`
NumberOfComments int `json:"num_comments"`
SubredditID string `json:"subreddit_id,omitempty"`
SubredditName string `json:"subreddit,omitempty"`
SubredditNamePrefixed string `json:"subreddit_name_prefixed,omitempty"`
AuthorID string `json:"author_fullname,omitempty"`
AuthorName string `json:"author,omitempty"`
Spoiler bool `json:"spoiler"`
Locked bool `json:"locked"`
NSFW bool `json:"over_18"`
IsSelfPost bool `json:"is_self"`
Saved bool `json:"saved"`
Stickied bool `json:"stickied"`
}
// Subreddit holds information about a subreddit
type Subreddit struct {
ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"`
URL string `json:"url,omitempty"`
Name string `json:"display_name,omitempty"`
NamePrefixed string `json:"display_name_prefixed,omitempty"`
Title string `json:"title,omitempty"`
PublicDescription string `json:"public_description,omitempty"`
Type string `json:"subreddit_type,omitempty"`
SuggestedCommentSort string `json:"suggested_comment_sort,omitempty"`
Subscribers int `json:"subscribers"`
ActiveUserCount *int `json:"active_user_count,omitempty"`
NSFW bool `json:"over18"`
UserIsMod bool `json:"user_is_moderator"`
}
func (rl *rootListing) getAfter() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.After
}
func (rl *rootListing) getBefore() string {
if rl == nil || rl.Data == nil {
return ""
}
return rl.Data.Before
}
func (rl *rootListing) getComments() *Comments {
if rl == nil || rl.Data == nil {
return nil
}
return &Comments{
Comments: rl.Data.Things.Comments,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getLinks() *Links {
if rl == nil || rl.Data == nil {
return nil
}
return &Links{
Links: rl.Data.Things.Links,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
func (rl *rootListing) getSubreddits() *Subreddits {
if rl == nil || rl.Data == nil {
return nil
}
return &Subreddits{
Subreddits: rl.Data.Things.Subreddits,
After: rl.Data.After,
Before: rl.Data.Before,
}
}
// Comments is a list of comments
type Comments struct {
Comments []Comment `json:"comments,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// Subreddits is a list of subreddits
type Subreddits struct {
Subreddits []Subreddit `json:"subreddits,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// Links is a list of links
type Links struct {
Links []Link `json:"submissions,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// CommentsLinks is a list of comments and links
type CommentsLinks struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// CommentsLinksSubreddits is a list of comments, links, and subreddits
type CommentsLinksSubreddits struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
}

88
user.go
View file

@ -17,34 +17,34 @@ type UserService interface {
Overview(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error) Overview(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error)
// returns the client's links // returns the client's links
GetHotLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) GetHotLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetNewLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) GetNewLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetTopLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) GetTopLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetControversialLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) GetControversialLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
// returns the links of the user with the username // returns the links of the user with the username
GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error)
GetUpvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) GetUpvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetDownvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) GetDownvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetHidden(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) GetHidden(ctx context.Context, opts *ListOptions) (*Links, *Response, error)
GetSaved(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error) GetSaved(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error)
GetGilded(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error) GetGilded(ctx context.Context, opts *ListOptions) (*CommentsLinks, *Response, error)
// returns the client's comments // returns the client's comments
GetHotComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) GetHotComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
GetNewComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) GetNewComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
GetTopComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) GetTopComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
GetControversialComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) GetControversialComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error)
// returns the comments of the user with the username // returns the comments of the user with the username
GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error)
Friend(ctx context.Context, username string, note string) (interface{}, *Response, error) Friend(ctx context.Context, username string, note string) (interface{}, *Response, error)
Unblock(ctx context.Context, username string) (*Response, error) Unblock(ctx context.Context, username string) (*Response, error)
@ -91,14 +91,6 @@ type UserShort struct {
NSFW bool `json:"profile_over_18"` NSFW bool `json:"profile_over_18"`
} }
// CommentsLinks holds comments and links
type CommentsLinks struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// Get returns information about the user // Get returns information about the user
func (s *UserServiceOp) Get(ctx context.Context, username string) (*User, *Response, error) { func (s *UserServiceOp) Get(ctx context.Context, username string) (*User, *Response, error) {
path := fmt.Sprintf("user/%s/about", username) path := fmt.Sprintf("user/%s/about", username)
@ -177,67 +169,67 @@ func (s *UserServiceOp) Overview(ctx context.Context, opts *ListOptions) (*Comme
} }
// GetHotLinks returns a list of the client's hottest submissions // GetHotLinks returns a list of the client's hottest submissions
func (s *UserServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetHotLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortHot]) path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortHot])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetNewLinks returns a list of the client's newest submissions // GetNewLinks returns a list of the client's newest submissions
func (s *UserServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetNewLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortNew]) path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortNew])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetTopLinks returns a list of the client's top submissions // GetTopLinks returns a list of the client's top submissions
func (s *UserServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetTopLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortTop]) path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortTop])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetControversialLinks returns a list of the client's most controversial submissions // GetControversialLinks returns a list of the client's most controversial submissions
func (s *UserServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetControversialLinks(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortControversial]) path := fmt.Sprintf("user/%s/submitted?sort=%s", s.client.Username, sorts[sortControversial])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetHotLinksOf returns a list of the user's hottest submissions // GetHotLinksOf returns a list of the user's hottest submissions
func (s *UserServiceOp) GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetHotLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortHot]) path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortHot])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetNewLinksOf returns a list of the user's newest submissions // GetNewLinksOf returns a list of the user's newest submissions
func (s *UserServiceOp) GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetNewLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortNew]) path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortNew])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetTopLinksOf returns a list of the user's top submissions // GetTopLinksOf returns a list of the user's top submissions
func (s *UserServiceOp) GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetTopLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortTop]) path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortTop])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetControversialLinksOf returns a list of the user's most controversial submissions // GetControversialLinksOf returns a list of the user's most controversial submissions
func (s *UserServiceOp) GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetControversialLinksOf(ctx context.Context, username string, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortControversial]) path := fmt.Sprintf("user/%s/submitted?sort=%s", username, sorts[sortControversial])
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetUpvoted returns a list of the client's upvoted submissions // GetUpvoted returns a list of the client's upvoted submissions
func (s *UserServiceOp) GetUpvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetUpvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/upvoted", s.client.Username) path := fmt.Sprintf("user/%s/upvoted", s.client.Username)
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetDownvoted returns a list of the client's downvoted submissions // GetDownvoted returns a list of the client's downvoted submissions
func (s *UserServiceOp) GetDownvoted(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetDownvoted(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/downvoted", s.client.Username) path := fmt.Sprintf("user/%s/downvoted", s.client.Username)
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
// GetHidden returns a list of the client's hidden submissions // GetHidden returns a list of the client's hidden submissions
func (s *UserServiceOp) GetHidden(ctx context.Context, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) GetHidden(ctx context.Context, opts *ListOptions) (*Links, *Response, error) {
path := fmt.Sprintf("user/%s/hidden", s.client.Username) path := fmt.Sprintf("user/%s/hidden", s.client.Username)
return s.getLinks(ctx, path, opts) return s.getLinks(ctx, path, opts)
} }
@ -255,42 +247,42 @@ func (s *UserServiceOp) GetGilded(ctx context.Context, opts *ListOptions) (*Comm
} }
// GetHotComments returns a list of the client's hottest comments // GetHotComments returns a list of the client's hottest comments
func (s *UserServiceOp) GetHotComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetHotComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortHot, opts) return s.getComments(ctx, s.client.Username, sortHot, opts)
} }
// GetNewComments returns a list of the client's newest comments // GetNewComments returns a list of the client's newest comments
func (s *UserServiceOp) GetNewComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetNewComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortNew, opts) return s.getComments(ctx, s.client.Username, sortNew, opts)
} }
// GetTopComments returns a list of the client's top comments // GetTopComments returns a list of the client's top comments
func (s *UserServiceOp) GetTopComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetTopComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortTop, opts) return s.getComments(ctx, s.client.Username, sortTop, opts)
} }
// GetControversialComments returns a list of the client's most controversial comments // GetControversialComments returns a list of the client's most controversial comments
func (s *UserServiceOp) GetControversialComments(ctx context.Context, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetControversialComments(ctx context.Context, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, s.client.Username, sortControversial, opts) return s.getComments(ctx, s.client.Username, sortControversial, opts)
} }
// GetHotCommentsOf returns a list of the user's hottest comments // GetHotCommentsOf returns a list of the user's hottest comments
func (s *UserServiceOp) GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetHotCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortHot, opts) return s.getComments(ctx, username, sortHot, opts)
} }
// GetNewCommentsOf returns a list of the user's newest comments // GetNewCommentsOf returns a list of the user's newest comments
func (s *UserServiceOp) GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetNewCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortNew, opts) return s.getComments(ctx, username, sortNew, opts)
} }
// GetTopCommentsOf returns a list of the user's top comments // GetTopCommentsOf returns a list of the user's top comments
func (s *UserServiceOp) GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetTopCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortTop, opts) return s.getComments(ctx, username, sortTop, opts)
} }
// GetControversialCommentsOf returns a list of the user's most controversial comments // GetControversialCommentsOf returns a list of the user's most controversial comments
func (s *UserServiceOp) GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) GetControversialCommentsOf(ctx context.Context, username string, opts *ListOptions) (*Comments, *Response, error) {
return s.getComments(ctx, username, sortControversial, opts) return s.getComments(ctx, username, sortControversial, opts)
} }
@ -344,7 +336,7 @@ func (s *UserServiceOp) Unfriend(ctx context.Context, username string) (*Respons
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
func (s *UserServiceOp) getLinks(ctx context.Context, path string, opts *ListOptions) (*LinkList, *Response, error) { func (s *UserServiceOp) getLinks(ctx context.Context, path string, opts *ListOptions) (*Links, *Response, error) {
path, err := addOptions(path, opts) path, err := addOptions(path, opts)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -364,7 +356,7 @@ func (s *UserServiceOp) getLinks(ctx context.Context, path string, opts *ListOpt
return root.getLinks(), resp, nil return root.getLinks(), resp, nil
} }
func (s *UserServiceOp) getComments(ctx context.Context, username string, sort sort, opts *ListOptions) (*CommentList, *Response, error) { func (s *UserServiceOp) getComments(ctx context.Context, username string, sort sort, opts *ListOptions) (*Comments, *Response, error) {
path := fmt.Sprintf("user/%s/comments?sort=%s", username, sorts[sort]) path := fmt.Sprintf("user/%s/comments?sort=%s", username, sorts[sort])
path, err := addOptions(path, opts) path, err := addOptions(path, opts)
if err != nil { if err != nil {