net-imap 0.4.12 → 0.4.21
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.
- checksums.yaml +4 -4
- data/lib/net/imap/command_data.rb +2 -2
- data/lib/net/imap/config/attr_accessors.rb +75 -0
- data/lib/net/imap/config/attr_inheritance.rb +90 -0
- data/lib/net/imap/config/attr_type_coercion.rb +65 -0
- data/lib/net/imap/config.rb +524 -0
- data/lib/net/imap/deprecated_client_options.rb +2 -2
- data/lib/net/imap/errors.rb +33 -0
- data/lib/net/imap/response_data.rb +3 -54
- data/lib/net/imap/response_parser/parser_utils.rb +6 -6
- data/lib/net/imap/response_parser.rb +34 -15
- data/lib/net/imap/response_reader.rb +75 -0
- data/lib/net/imap/sequence_set.rb +274 -123
- data/lib/net/imap/uidplus_data.rb +326 -0
- data/lib/net/imap.rb +297 -86
- data/net-imap.gemspec +2 -2
- metadata +9 -9
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/pages.yml +0 -46
- data/.github/workflows/push_gem.yml +0 -48
- data/.github/workflows/test.yml +0 -31
- data/.gitignore +0 -12
- data/.mailmap +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab1b84ea6eac7b0d57793127bc365c79b63eb9564386427eb66cca91cf5df294
|
4
|
+
data.tar.gz: 3040f462d83f7a364fed076a730d5a9ba0512ea52ab0368765befb0e2d700dd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7565d3002323cdaad204bbd5eceb0b64d265e61daa41d9e3c61b8ea12ff3bbbb5f5e62298138f48a96c32553b1fcf3c6dcab7cae5776a22a521abe77b6e153c
|
7
|
+
data.tar.gz: 73b9338a55d33e703c86217ee80ee7486e92dbf67b232c152d4115a89a76c4f384c39e34888d24ec8cf389af1d67ca1d1d84e3edc676ecc501495cf6b66d7dfe
|
@@ -40,10 +40,10 @@ module Net
|
|
40
40
|
send_number_data(data)
|
41
41
|
when Array
|
42
42
|
send_list_data(data, tag)
|
43
|
-
when Date
|
44
|
-
send_date_data(data)
|
45
43
|
when Time, DateTime
|
46
44
|
send_time_data(data)
|
45
|
+
when Date
|
46
|
+
send_date_data(data)
|
47
47
|
when Symbol
|
48
48
|
send_symbol_data(data)
|
49
49
|
else
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module Net
|
6
|
+
class IMAP
|
7
|
+
class Config
|
8
|
+
# >>>
|
9
|
+
# *NOTE:* This module is an internal implementation detail, with no
|
10
|
+
# guarantee of backward compatibility.
|
11
|
+
#
|
12
|
+
# +attr_accessor+ values are stored in a struct rather than ivars, making
|
13
|
+
# it simpler to ensure that all config objects share a single object
|
14
|
+
# shape. This also simplifies iteration over all defined attributes.
|
15
|
+
module AttrAccessors
|
16
|
+
module Macros # :nodoc: internal API
|
17
|
+
def attr_accessor(name) AttrAccessors.attr_accessor(name) end
|
18
|
+
end
|
19
|
+
private_constant :Macros
|
20
|
+
|
21
|
+
def self.included(mod)
|
22
|
+
mod.extend Macros
|
23
|
+
end
|
24
|
+
private_class_method :included
|
25
|
+
|
26
|
+
extend Forwardable
|
27
|
+
|
28
|
+
def self.attr_accessor(name) # :nodoc: internal API
|
29
|
+
name = name.to_sym
|
30
|
+
def_delegators :data, name, :"#{name}="
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.attributes
|
34
|
+
instance_methods.grep(/=\z/).map { _1.to_s.delete_suffix("=").to_sym }
|
35
|
+
end
|
36
|
+
private_class_method :attributes
|
37
|
+
|
38
|
+
def self.struct # :nodoc: internal API
|
39
|
+
unless defined?(self::Struct)
|
40
|
+
const_set :Struct, Struct.new(*attributes)
|
41
|
+
end
|
42
|
+
self::Struct
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize # :notnew:
|
46
|
+
super()
|
47
|
+
@data = AttrAccessors.struct.new
|
48
|
+
end
|
49
|
+
|
50
|
+
# Freezes the internal attributes struct, in addition to +self+.
|
51
|
+
def freeze
|
52
|
+
data.freeze
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
attr_reader :data # :nodoc: internal API
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def initialize_clone(other)
|
63
|
+
super
|
64
|
+
@data = other.data.clone
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize_dup(other)
|
68
|
+
super
|
69
|
+
@data = other.data.dup
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class IMAP
|
5
|
+
class Config
|
6
|
+
# >>>
|
7
|
+
# *NOTE:* The public methods on this module are part of the stable
|
8
|
+
# public API of Net::IMAP::Config. But the module itself is an internal
|
9
|
+
# implementation detail, with no guarantee of backward compatibility.
|
10
|
+
#
|
11
|
+
# +attr_accessor+ methods will delegate to their #parent when the local
|
12
|
+
# value does not contain an override. Inheritance forms a singly linked
|
13
|
+
# list, so lookup will be <tt>O(n)</tt> on the number of ancestors. In
|
14
|
+
# practice, the ancestor chain is not expected to be long. Without
|
15
|
+
# customization, it is only three deep:
|
16
|
+
# >>>
|
17
|
+
# IMAP#config → Config.global → Config.default
|
18
|
+
#
|
19
|
+
# When creating a client with the +config+ keyword, for example to use
|
20
|
+
# the appropriate defaults for an application or a library while still
|
21
|
+
# relying on global for configuration of +debug+ or +logger+, most likely
|
22
|
+
# the ancestor chain is still only four deep:
|
23
|
+
# >>>
|
24
|
+
# IMAP#config → alternate defaults → Config.global → Config.default
|
25
|
+
module AttrInheritance
|
26
|
+
INHERITED = Module.new.freeze
|
27
|
+
private_constant :INHERITED
|
28
|
+
|
29
|
+
module Macros # :nodoc: internal API
|
30
|
+
def attr_accessor(name) super; AttrInheritance.attr_accessor(name) end
|
31
|
+
end
|
32
|
+
private_constant :Macros
|
33
|
+
|
34
|
+
def self.included(mod)
|
35
|
+
mod.extend Macros
|
36
|
+
end
|
37
|
+
private_class_method :included
|
38
|
+
|
39
|
+
def self.attr_accessor(name) # :nodoc: internal API
|
40
|
+
module_eval <<~RUBY, __FILE__, __LINE__ + 1
|
41
|
+
def #{name}; (val = super) == INHERITED ? parent&.#{name} : val end
|
42
|
+
RUBY
|
43
|
+
end
|
44
|
+
|
45
|
+
# The parent Config object
|
46
|
+
attr_reader :parent
|
47
|
+
|
48
|
+
def initialize(parent = nil) # :notnew:
|
49
|
+
super()
|
50
|
+
@parent = Config[parent]
|
51
|
+
reset
|
52
|
+
end
|
53
|
+
|
54
|
+
# Creates a new config, which inherits from +self+.
|
55
|
+
def new(**attrs) self.class.new(self, **attrs) end
|
56
|
+
|
57
|
+
# Returns +true+ if +attr+ is inherited from #parent and not overridden
|
58
|
+
# by this config.
|
59
|
+
def inherited?(attr) data[attr] == INHERITED end
|
60
|
+
|
61
|
+
# :call-seq:
|
62
|
+
# reset -> self
|
63
|
+
# reset(attr) -> attribute value
|
64
|
+
#
|
65
|
+
# Resets an +attr+ to inherit from the #parent config.
|
66
|
+
#
|
67
|
+
# When +attr+ is nil or not given, all attributes are reset.
|
68
|
+
def reset(attr = nil)
|
69
|
+
if attr.nil?
|
70
|
+
data.members.each do |attr| data[attr] = INHERITED end
|
71
|
+
self
|
72
|
+
elsif inherited?(attr)
|
73
|
+
nil
|
74
|
+
else
|
75
|
+
old, data[attr] = data[attr], INHERITED
|
76
|
+
old
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def initialize_copy(other)
|
83
|
+
super
|
84
|
+
@parent ||= other # only default has nil parent
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class IMAP
|
5
|
+
class Config
|
6
|
+
# >>>
|
7
|
+
# *NOTE:* This module is an internal implementation detail, with no
|
8
|
+
# guarantee of backward compatibility.
|
9
|
+
#
|
10
|
+
# Adds a +type+ keyword parameter to +attr_accessor+, to enforce that
|
11
|
+
# config attributes have valid types, for example: boolean, numeric,
|
12
|
+
# enumeration, non-nullable, etc.
|
13
|
+
module AttrTypeCoercion
|
14
|
+
# :stopdoc: internal APIs only
|
15
|
+
|
16
|
+
module Macros # :nodoc: internal API
|
17
|
+
def attr_accessor(attr, type: nil)
|
18
|
+
super(attr)
|
19
|
+
AttrTypeCoercion.attr_accessor(attr, type: type)
|
20
|
+
end
|
21
|
+
|
22
|
+
module_function def Integer?; NilOrInteger end
|
23
|
+
end
|
24
|
+
private_constant :Macros
|
25
|
+
|
26
|
+
def self.included(mod)
|
27
|
+
mod.extend Macros
|
28
|
+
end
|
29
|
+
private_class_method :included
|
30
|
+
|
31
|
+
if defined?(Ractor.make_shareable)
|
32
|
+
def self.safe(...) Ractor.make_shareable nil.instance_eval(...).freeze end
|
33
|
+
else
|
34
|
+
def self.safe(...) nil.instance_eval(...).freeze end
|
35
|
+
end
|
36
|
+
private_class_method :safe
|
37
|
+
|
38
|
+
Types = Hash.new do |h, type|
|
39
|
+
type.nil? || Proc === type or raise TypeError, "type not nil or Proc"
|
40
|
+
safe{type}
|
41
|
+
end
|
42
|
+
Types[:boolean] = Boolean = safe{-> {!!_1}}
|
43
|
+
Types[Integer] = safe{->{Integer(_1)}}
|
44
|
+
|
45
|
+
def self.attr_accessor(attr, type: nil)
|
46
|
+
type = Types[type] or return
|
47
|
+
define_method :"#{attr}=" do |val| super type[val] end
|
48
|
+
define_method :"#{attr}?" do send attr end if type == Boolean
|
49
|
+
end
|
50
|
+
|
51
|
+
NilOrInteger = safe{->val { Integer val unless val.nil? }}
|
52
|
+
|
53
|
+
Enum = ->(*enum) {
|
54
|
+
enum = safe{enum}
|
55
|
+
expected = -"one of #{enum.map(&:inspect).join(", ")}"
|
56
|
+
safe{->val {
|
57
|
+
return val if enum.include?(val)
|
58
|
+
raise ArgumentError, "expected %s, got %p" % [expected, val]
|
59
|
+
}}
|
60
|
+
}
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|