thumbtack 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/lib/thumbtack/client.rb +70 -0
  3. data/lib/thumbtack/note.rb +35 -0
  4. data/lib/thumbtack/note_summary.rb +35 -0
  5. data/lib/thumbtack/notes.rb +26 -0
  6. data/lib/thumbtack/post.rb +37 -0
  7. data/lib/thumbtack/posts.rb +186 -0
  8. data/lib/thumbtack/specification.rb +31 -0
  9. data/lib/thumbtack/tags.rb +45 -0
  10. data/lib/thumbtack/types/boolean.rb +52 -0
  11. data/lib/thumbtack/types/date.rb +47 -0
  12. data/lib/thumbtack/types/date_time.rb +49 -0
  13. data/lib/thumbtack/types/identity.rb +26 -0
  14. data/lib/thumbtack/types/integer.rb +27 -0
  15. data/lib/thumbtack/types/md5.rb +30 -0
  16. data/lib/thumbtack/types/tags.rb +53 -0
  17. data/lib/thumbtack/types/text.rb +26 -0
  18. data/lib/thumbtack/types/title.rb +26 -0
  19. data/lib/thumbtack/types/url.rb +26 -0
  20. data/lib/thumbtack/types.rb +10 -0
  21. data/lib/thumbtack/user.rb +23 -0
  22. data/lib/thumbtack/version.rb +6 -0
  23. data/lib/thumbtack.rb +32 -0
  24. data/test/test_helper.rb +18 -0
  25. data/test/thumbtack/client_test.rb +35 -0
  26. data/test/thumbtack/note_summary_test.rb +24 -0
  27. data/test/thumbtack/note_test.rb +26 -0
  28. data/test/thumbtack/notes_test.rb +61 -0
  29. data/test/thumbtack/post_test.rb +30 -0
  30. data/test/thumbtack/posts_test.rb +178 -0
  31. data/test/thumbtack/specification_test.rb +15 -0
  32. data/test/thumbtack/tags_test.rb +56 -0
  33. data/test/thumbtack/types/boolean_test.rb +28 -0
  34. data/test/thumbtack/types/date_test.rb +27 -0
  35. data/test/thumbtack/types/date_time_test.rb +27 -0
  36. data/test/thumbtack/types/identity_test.rb +18 -0
  37. data/test/thumbtack/types/integer_test.rb +26 -0
  38. data/test/thumbtack/types/md5_test.rb +28 -0
  39. data/test/thumbtack/types/tags_test.rb +29 -0
  40. data/test/thumbtack/types/text_test.rb +22 -0
  41. data/test/thumbtack/types/title_test.rb +22 -0
  42. data/test/thumbtack/types/url_test.rb +23 -0
  43. data/test/thumbtack/user_test.rb +29 -0
  44. metadata +162 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3d86b3db897475f83812368d11f5179d8b098af6
4
+ data.tar.gz: d92ba1381ba92772a4b7610b70c3d53a839f0f1d
5
+ SHA512:
6
+ metadata.gz: d9ad33c40ef19811c378c9bbc6f09e54151ecb5a8c657ad05f48916f0a1b4e87ce152a1508c51a6ae290257287c5a7d0cbd463fe68dae6296a0502e5cddc2ef8
7
+ data.tar.gz: 32bd3769072670a57804a306fc46f78db993dbc6e91bd395a7433491c74381a13176f900429faab5f82b45f2b5e3a862e8e286c7636894631e9c949e4c3026e1
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Public: Wraps each interaction with the Pinboard API.
5
+ class Client
6
+ # Public: String of base Pinboard API URL.
7
+ BASE_URL = 'https://api.pinboard.in/v1'.freeze
8
+
9
+ # Public: Returns the String username being used by the client.
10
+ attr_reader :username
11
+
12
+ # Public: Returns the String API token being used by the client.
13
+ attr_reader :token
14
+
15
+ # Public: Creates a new client.
16
+ #
17
+ # username - A String naming the user account to authenticate with.
18
+ # token - A String of the API token for the user account. Can be found on
19
+ # the user's settings page.
20
+ def initialize(username, token)
21
+ @username, @token = username, token
22
+ end
23
+
24
+ # Internal: Request JSON from the Pinboard API.
25
+ #
26
+ # path - A String of the path to fetch from. The is relative from the root
27
+ # Pinboard API URL.
28
+ # params - A Hash of query parameters to append to the URL for the fetch
29
+ # (default: {}).
30
+ #
31
+ # Examples
32
+ #
33
+ # get('/posts/update')
34
+ # # => {'update_time' => '2014-06-24T15:39:46Z'}
35
+ #
36
+ # get('/posts/suggest', url: 'http://theinternate.com/')
37
+ # # => [{'popular' => []}, {'recommended' => []}]
38
+ #
39
+ # Returns a parsed JSON response from Pinboard's API.
40
+ def get(path, params = {})
41
+ uri = URI("#{BASE_URL}#{path}")
42
+
43
+ base_params = { auth_token: "#{@username}:#{@token}", format: 'json' }
44
+ uri.query = URI.encode_www_form(params.merge(base_params))
45
+
46
+ response = Net::HTTP.get_response(uri)
47
+ JSON.parse(response.body)
48
+ end
49
+
50
+ # Public: Access posts-related API calls.
51
+ def posts
52
+ Posts.new(self)
53
+ end
54
+
55
+ # Public: Access tags-related API calls.
56
+ def tags
57
+ Tags.new(self)
58
+ end
59
+
60
+ # Public: Access user-related API calls.
61
+ def user
62
+ User.new(self)
63
+ end
64
+
65
+ # Public: Access notes-related API calls.
66
+ def notes
67
+ Notes.new(self)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Public: Represents a note.
5
+ class Note
6
+ # Private: The attributes for a Note.
7
+ ATTRIBUTES = [
8
+ :id,
9
+ :title,
10
+ :hash,
11
+ :created_at,
12
+ :updated_at,
13
+ :text,
14
+ :length
15
+ ].freeze
16
+
17
+ attr_reader(*ATTRIBUTES)
18
+
19
+ # Internal: Creates a new Note from a Hash, usually a Client#get response.
20
+ #
21
+ # hash - A Hash of attributes of the note.
22
+ def self.from_hash(hash)
23
+ new(Hash[hash.map { |key, value| [key.to_sym, value] }])
24
+ end
25
+
26
+ # Internal: Initialize a Note.
27
+ #
28
+ # attrs - A Hash of attributes of the Note.
29
+ def initialize(attrs = {})
30
+ ATTRIBUTES.each do |attribute|
31
+ instance_variable_set "@#{attribute}", attrs.fetch(attribute)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Public: Represents a note summary as returned from Notes#list.
5
+ class NoteSummary
6
+ # Private: The attributes for a NoteSummary.
7
+ ATTRIBUTES = [
8
+ :id,
9
+ :title,
10
+ :hash,
11
+ :created_at,
12
+ :updated_at,
13
+ :length
14
+ ].freeze
15
+
16
+ attr_reader(*ATTRIBUTES)
17
+
18
+ # Internal: Creates a new NoteSummary from a Hash, usually a Client#get
19
+ # response.
20
+ #
21
+ # hash - A Hash of attributes of the note.
22
+ def self.from_hash(hash)
23
+ new(Hash[hash.map { |key, value| [key.to_sym, value] }])
24
+ end
25
+
26
+ # Internal: Initialize a NoteSummary.
27
+ #
28
+ # attrs - A Hash of attributes of the NoteSummary.
29
+ def initialize(attrs = {})
30
+ ATTRIBUTES.each do |attribute|
31
+ instance_variable_set "@#{attribute}", attrs.fetch(attribute)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Internal: Wraps API calls related to notes.
5
+ class Notes
6
+ # Internal: Creates a new Notes.
7
+ #
8
+ # client - a Thumbtack::Client to communicate with the Pinboard API.
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # Public: Returns a list of summaries of the user's notes.
14
+ def list
15
+ response = @client.get('/notes/list')
16
+ response.fetch('notes', []).map do |note_hash|
17
+ NoteSummary.from_hash(note_hash)
18
+ end
19
+ end
20
+
21
+ # Public: Return an individual note.
22
+ def get(id)
23
+ Note.from_hash @client.get("/notes/#{id}")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Public: Represents a bookmark.
5
+ class Post
6
+ # Private: The attributes for a Post.
7
+ ATTRIBUTES = [
8
+ :href,
9
+ :description,
10
+ :extended,
11
+ :meta,
12
+ :hash,
13
+ :time,
14
+ :shared,
15
+ :toread,
16
+ :tags
17
+ ].freeze
18
+
19
+ attr_reader(*ATTRIBUTES)
20
+
21
+ # Internal: Creates a new post from a Hash, usually a Client#get response.
22
+ #
23
+ # hash - A Hash of attributes of the Post.
24
+ def self.from_hash(hash)
25
+ new(Hash[hash.map { |key, value| [key.to_sym, value] }])
26
+ end
27
+
28
+ # Internal: Initialize a Post.
29
+ #
30
+ # attrs - A Hash of attributes of the Post.
31
+ def initialize(attrs = {})
32
+ ATTRIBUTES.each do |attribute|
33
+ instance_variable_set "@#{attribute}", attrs.fetch(attribute)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,186 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Internal: Wraps API calls related to posts.
5
+ class Posts
6
+ # Internal: Initialize a Posts.
7
+ #
8
+ # client - A Thumbtack::Client to communicate with the Pinboard API.
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # Public: The most recent time a bookmark was added, updated, or deleted.
14
+ #
15
+ # Examples
16
+ #
17
+ # update
18
+ # # => '2014-06-26T19:01:33Z'
19
+ #
20
+ # Returns a DateTime in UTC.
21
+ def update
22
+ response = @client.get('/posts/update')
23
+ Types::DateTime.from_parameter response.fetch('update_time')
24
+ end
25
+
26
+ # Public: Add a bookmark.
27
+ #
28
+ # url - A String containing the URL to be bookmarked.
29
+ # description - A String containing the title of the bookmark.
30
+ # options - The Hash options to be passed as arguments.
31
+ # :extended - A String containing a description of the item.
32
+ # :tags - An Array containing up to 100 tags.
33
+ # :dt - A DateTime containing the creation time for this
34
+ # bookmark.
35
+ # :replace - A Boolean containing whether or not to replace any
36
+ # existing bookmark with this URL.
37
+ # :shared - A Boolean containing whether or not to make the
38
+ # bookmark public.
39
+ # :toread - A Boolean containing whether or not to mark the
40
+ # bookmark as unread.
41
+ #
42
+ # Examples
43
+ #
44
+ # add('http://theinternate.com', 'The Internate')
45
+ # add('http://theinternate.com', 'The Internate', tags: ['best', 'ruby'])
46
+ #
47
+ # Returns the Posts instance.
48
+ def add(url, description, options = {})
49
+ parameters = Specification.new(
50
+ url: Types::URL,
51
+ description: Types::Text,
52
+ extended: Types::Text,
53
+ tags: Types::Tags,
54
+ dt: Types::DateTime,
55
+ replace: Types::Boolean,
56
+ shared: Types::Boolean,
57
+ toread: Types::Boolean
58
+ ).parameters({ url: url, description: description }.merge(options))
59
+ @client.get('/posts/add', parameters)
60
+ self
61
+ end
62
+
63
+ # Public: Delete a bookmark.
64
+ #
65
+ # url - A String containing the URL of the bookmark to delete.
66
+ #
67
+ # Examples
68
+ #
69
+ # delete('http://delicio.us')
70
+ #
71
+ # Returns the Posts instance
72
+ def delete(url)
73
+ parameters = Specification.new(url: Types::URL).parameters(url: url)
74
+ @client.get('/posts/delete', parameters)
75
+ self
76
+ end
77
+
78
+ # Public: Return one or more posts matching the arguments.
79
+ #
80
+ # options - The Hash options to be passed as arguments.
81
+ # :tag - An Array containing a up to three tags to filter by.
82
+ # :dt - A DateTime containing the date when the results were
83
+ # bookmarked.
84
+ # :url - A String containing the URL for the the bookmark.
85
+ # :meta - A Boolean indicating whether or not to include a change
86
+ # detection signature.
87
+ #
88
+ # Examples
89
+ #
90
+ # get(tag: 'webdev', meta: 'yes')
91
+ # get(url: 'http://www.pinboard.in')
92
+ #
93
+ # Returns a list of Post instances.
94
+ def get(options = {})
95
+ parameters = Specification.new(
96
+ tag: Types::Tags,
97
+ dt: Types::DateTime,
98
+ url: Types::URL,
99
+ meta: Types::Boolean
100
+ ).parameters(options)
101
+ posts_from @client.get('/posts/get', parameters)
102
+ end
103
+
104
+ # Public: Return a list of the most recent posts.
105
+ #
106
+ # options - The Hash options to be passed as arguments.
107
+ # :tag - An Array containing a up to three tags to filter by.
108
+ # :count - An Integer of the number of results to return. Default
109
+ # is 15, maximum is 100.
110
+ #
111
+ # Examples
112
+ #
113
+ # recent(tag: 'webdev', count: 25)
114
+ #
115
+ # Returns a list of Post instances.
116
+ def recent(options = {})
117
+ parameters = Specification.new(
118
+ tag: Types::Tags,
119
+ count: Types::Integer
120
+ ).parameters(options)
121
+ posts_from @client.get('/posts/recent', parameters)
122
+ end
123
+
124
+ # Public: Return all posts in the account.
125
+ #
126
+ # options - The Hash options to be passed as arguments.
127
+ # :tag - A String containing a list of up to three tags to
128
+ # filter by.
129
+ # :start - An Integer offset value. Default is 0.
130
+ # :results - An Integer of the number of results to return.
131
+ # :fromdt - Filter results to posts created after this DateTime.
132
+ # :todt - Filter results to posts created before this DateTime.
133
+ # :meta - A Boolean containing whether or not to include a
134
+ # change detection signature.
135
+ #
136
+ # Returns a list of Posts instances
137
+ def all(options = {})
138
+ parameters = Specification.new(
139
+ tag: Types::Tags,
140
+ start: Types::Integer,
141
+ results: Types::Integer,
142
+ fromdt: Types::DateTime,
143
+ todt: Types::DateTime,
144
+ meta: Types::Boolean
145
+ ).parameters(options)
146
+ results = @client.get('/posts/all', parameters)
147
+ results.map { |post_hash| Post.from_hash(post_hash) }
148
+ end
149
+
150
+ # Public: Return a list of popular and recommended tags for a URL.
151
+ #
152
+ # url - A String containing a URL to fetch suggested tags for.
153
+ #
154
+ # Returns a Hash with two entries, :popular is a list of popular tags,
155
+ # :recommended is a list of recommended tags.
156
+ def suggest(url)
157
+ parameters = Specification.new(url: Types::URL).parameters(url: url)
158
+ result = @client.get('/posts/suggest', parameters)
159
+ { popular: result.fetch('popular'),
160
+ recommended: result.fetch('recommended') }
161
+ end
162
+
163
+ # Public: Return a list dates with the count of posts made at each date.
164
+ #
165
+ # options - The Hash options to be passed as arguments
166
+ # :tag - An Array containing a up to three tags to filter by.
167
+ #
168
+ # Returns a Hash of Strings => Integer entries. The Strings contain a date
169
+ # and the Integer is the count of posts made on that date.
170
+ def dates(options = {})
171
+ parameters = Specification.new(tag: Types::Tags).parameters(options)
172
+ response = @client.get('/posts/dates', parameters)
173
+ Hash[
174
+ response.fetch('dates', {}).map do |date, count|
175
+ [Types::Date.from_parameter(date), count.to_i]
176
+ end
177
+ ]
178
+ end
179
+
180
+ private
181
+
182
+ def posts_from(response)
183
+ response.fetch('posts', []).map { |post_hash| Post.from_hash(post_hash) }
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Internal: Validates and translates user-provided parameters to their
5
+ # Pinboard-supported equivalents
6
+ class Specification
7
+
8
+ # Create a new Specification.
9
+ #
10
+ # type_handlers - A Hash mapping parameter names to their type handlers.
11
+ def initialize(type_handlers)
12
+ @type_handlers = type_handlers
13
+ end
14
+
15
+ # Validate and translate user-provided parameters to their
16
+ # Pinboard-supported equivalents.
17
+ #
18
+ # arguments - A Hash mapping parameter names to their user-provided values.
19
+ #
20
+ # Returns the parameters translated to their Pinboard equivalents.
21
+ def parameters(arguments)
22
+ Hash[
23
+ arguments.map do |name, value|
24
+ type_handler = @type_handlers.fetch(name)
25
+ type_handler.validate(value)
26
+ [name, type_handler.to_parameter(value)]
27
+ end
28
+ ]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ # Internal: Wraps API calls related to tags.
5
+ class Tags
6
+ # Internal: Creates a new Tags.
7
+ #
8
+ # client - a Thumbtack::Client to communicate with the Pinboard API.
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # Public: Returns a list of the user's tags with their counts.
14
+ def get
15
+ response = @client.get('/tags/get')
16
+ Hash[response.map { |tag, count| [tag, count.to_i] }]
17
+ end
18
+
19
+ # Public: Delete a tag.
20
+ #
21
+ # tag - A String containing the tag to delete.
22
+ #
23
+ # Returns the Tags instance.
24
+ def delete(tag)
25
+ parameters = Specification.new(tag: Types::Tags).parameters(tag: tag)
26
+ @client.get('/tags/delete', parameters)
27
+ self
28
+ end
29
+
30
+ # Public: Rename a tag.
31
+ #
32
+ # old - A String containing the tag to be renamed.
33
+ # new - A String containing the new name for the tag.
34
+ #
35
+ # Returns the Tags instance.
36
+ def rename(old, new)
37
+ parameters = Specification.new(
38
+ old: Types::Tags,
39
+ new: Types::Tags
40
+ ).parameters(old: old, new: new)
41
+ @client.get('/tags/rename', parameters)
42
+ self
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ module Types
5
+ # Internal: Handles conversion and validation of Boolean types to the 'yes'
6
+ # and 'no' parameters supported by the Pinboard API.
7
+ class Boolean
8
+ # Validate something is a Boolean parameter.
9
+ #
10
+ # value - A Boolean to validate.
11
+ #
12
+ # Returns nothing.
13
+ # Raises Types::ValidationError if the value is not true or false
14
+ def self.validate(value)
15
+ case value
16
+ when TrueClass, FalseClass
17
+ self
18
+ else
19
+ fail ValidationError, "#{value} must be true or false"
20
+ end
21
+ end
22
+
23
+ # Convert a Boolean value to a parameter acceptable to the Pinboard API.
24
+ #
25
+ # value - A Boolean to convert.
26
+ #
27
+ # Returns 'yes' or 'no'
28
+ def self.to_parameter(value)
29
+ case value
30
+ when TrueClass
31
+ 'yes'
32
+ when FalseClass
33
+ 'no'
34
+ end
35
+ end
36
+
37
+ # Convert a parameter from the Pinboard API to a Ruby Boolean.
38
+ #
39
+ # parameter - A String containing 'yes' or 'no'.
40
+ #
41
+ # Returns true or false.
42
+ def self.from_parameter(parameter)
43
+ case parameter
44
+ when 'yes'
45
+ true
46
+ when 'no'
47
+ false
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ module Types
5
+ # Internal: Handles conversion and validation of Date types to the String
6
+ # parameters supported by the Pinboard API.
7
+ class Date
8
+ # The earliest allowable date
9
+ EARLIEST = ::Date.new(1, 1, 1)
10
+ # The latest allowable date
11
+ LATEST = ::Date.new(2100, 1, 1)
12
+
13
+ # Validate a Date.
14
+ #
15
+ # value - The Date to validate.
16
+ #
17
+ # Returns nothing.
18
+ # Raises Types::ValidationError if the date is not between 0001-01-01 and
19
+ # 2100-01-01.
20
+ def self.validate(value)
21
+ unless value > EARLIEST && value < LATEST
22
+ fail ValidationError,
23
+ "#{value} must be between 0001-01-01 and 2100-01-01"
24
+ end
25
+ self
26
+ end
27
+
28
+ # Convert a Date value to a parameter acceptable to the Pinboard API.
29
+ #
30
+ # value - The Date to convert.
31
+ #
32
+ # Returns a String containing the date with format yyyy-mm-dd.
33
+ def self.to_parameter(value)
34
+ value.xmlschema
35
+ end
36
+
37
+ # Convert a parameter from the Pinboard API to a Ruby Date.
38
+ #
39
+ # parameter - A String of the date formatted yyyy-mm-dd.
40
+ #
41
+ # Returns a Date.
42
+ def self.from_parameter(parameter)
43
+ ::Date.xmlschema(parameter)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ module Types
5
+ # Handles conversion and validation of DateTime types to the String
6
+ # parameters supported by the Pinboard API.
7
+ class DateTime
8
+ # The earliest allowable time
9
+ EARLIEST = ::DateTime.new(1, 1, 1)
10
+ # The latest allowable time
11
+ LATEST = ::DateTime.new(2100, 1, 1)
12
+ # The date format of the Pinboard API
13
+ FORMAT = '%Y-%m-%dT%H:%M:%SZ'.freeze
14
+
15
+ # Validate something is a valid DateTime parameter.
16
+ #
17
+ # value - The DateTime to validate.
18
+ #
19
+ # Returns nothing.
20
+ # Raises Types::ValidationError if the time is not between
21
+ # 0001-01-01 00:00:00 and 2100-01-01 00:00:00.
22
+ def self.validate(value)
23
+ unless value > EARLIEST && value < LATEST
24
+ fail ValidationError,
25
+ "#{value} must be between 0001-01-01 and 2100-01-01"
26
+ end
27
+ self
28
+ end
29
+
30
+ # Convert a DateTime value to a parameter acceptable to the Pinboard API.
31
+ #
32
+ # value - The DateTime to convert.
33
+ #
34
+ # Returns a String containing the date with format yyyy-mm-ddTHH:MM:SSZ.
35
+ def self.to_parameter(value)
36
+ value.strftime(FORMAT)
37
+ end
38
+
39
+ # Convert a parameter from the Pinboard API to a Ruby DateTime.
40
+ #
41
+ # parameter - A String of the date formatted yyyy-mm-ddTHH:MM:SSZ.
42
+ #
43
+ # Returns a DateTime.
44
+ def self.from_parameter(parameter)
45
+ ::DateTime.strptime(parameter)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ module Types
5
+ # Internal: An abstract type handler
6
+ class Identity
7
+
8
+ # Any value passed is valid.
9
+ #
10
+ # Returns nothing.
11
+ def self.validate(*)
12
+ self
13
+ end
14
+
15
+ # Return any value passed to this without conversion.
16
+ def self.to_parameter(value)
17
+ value
18
+ end
19
+
20
+ # Return any value passed to this without conversion.
21
+ def self.from_parameter(parameter)
22
+ parameter
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ module Thumbtack
4
+ module Types
5
+ # Internal: Handles validation of Integer types as the values supported by
6
+ # the Pinboard API.
7
+ class Integer < Identity
8
+ # The minimum allowable integer.
9
+ MIN = 0
10
+ # The maximum allowable integer.
11
+ MAX = 2**32
12
+
13
+ # Validate something is a valid integer parameter.
14
+ #
15
+ # value - An integer to validate.
16
+ #
17
+ # Returns nothing.
18
+ # Raises Types::ValidationError if the value is not between 0 and 2^32.
19
+ def self.validate(value)
20
+ unless value >= MIN && value <= MAX
21
+ fail ValidationError, "#{value} must be in range 0..2^32"
22
+ end
23
+ self
24
+ end
25
+ end
26
+ end
27
+ end