nrser 0.3.9 → 0.3.10

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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nrser/char/alpha_numeric_sub.rb +9 -19
  3. data/lib/nrser/char/special.rb +5 -5
  4. data/lib/nrser/core_ext/array.rb +36 -13
  5. data/lib/nrser/core_ext/enumerable.rb +1 -0
  6. data/lib/nrser/core_ext/enumerable/find_map.rb +1 -1
  7. data/lib/nrser/core_ext/hash/bury.rb +3 -0
  8. data/lib/nrser/core_ext/hash/extract_values_at.rb +2 -2
  9. data/lib/nrser/core_ext/method/full_name.rb +1 -1
  10. data/lib/nrser/core_ext/module/method_objects.rb +1 -1
  11. data/lib/nrser/core_ext/module/source_locations.rb +27 -15
  12. data/lib/nrser/core_ext/object/lazy_var.rb +1 -1
  13. data/lib/nrser/core_ext/pathname.rb +67 -12
  14. data/lib/nrser/core_ext/pathname/subpath.rb +86 -0
  15. data/lib/nrser/core_ext/string.rb +28 -1
  16. data/lib/nrser/core_ext/symbol.rb +11 -12
  17. data/lib/nrser/errors/README.md +154 -0
  18. data/lib/nrser/errors/attr_error.rb +146 -53
  19. data/lib/nrser/errors/count_error.rb +61 -12
  20. data/lib/nrser/errors/nicer_error.rb +42 -71
  21. data/lib/nrser/errors/value_error.rb +53 -58
  22. data/lib/nrser/functions.rb +0 -2
  23. data/lib/nrser/functions/enumerable.rb +5 -17
  24. data/lib/nrser/functions/enumerable/associate.rb +14 -5
  25. data/lib/nrser/functions/enumerable/find_all_map.rb +1 -1
  26. data/lib/nrser/functions/enumerable/include_slice/array_include_slice.rb +1 -1
  27. data/lib/nrser/functions/hash/bury.rb +2 -12
  28. data/lib/nrser/functions/merge_by.rb +2 -2
  29. data/lib/nrser/functions/module/method_objects.rb +2 -2
  30. data/lib/nrser/functions/path.rb +185 -165
  31. data/lib/nrser/functions/path/normalized.rb +84 -0
  32. data/lib/nrser/functions/string.rb +4 -4
  33. data/lib/nrser/functions/text/README.md +4 -0
  34. data/lib/nrser/functions/text/format.rb +53 -0
  35. data/lib/nrser/functions/text/indentation.rb +6 -6
  36. data/lib/nrser/functions/text/word_wrap.rb +2 -2
  37. data/lib/nrser/functions/tree/map_leaves.rb +3 -3
  38. data/lib/nrser/functions/tree/map_tree.rb +2 -2
  39. data/lib/nrser/functions/tree/transform.rb +1 -18
  40. data/lib/nrser/gem_ext/README.md +4 -0
  41. data/lib/nrser/labs/README.md +8 -0
  42. data/lib/nrser/labs/config.rb +163 -0
  43. data/lib/nrser/labs/i8.rb +49 -159
  44. data/lib/nrser/labs/i8/struct.rb +167 -0
  45. data/lib/nrser/labs/i8/struct/hash.rb +140 -0
  46. data/lib/nrser/labs/i8/struct/vector.rb +149 -0
  47. data/lib/nrser/labs/i8/surjection.rb +211 -0
  48. data/lib/nrser/labs/lots/consumer.rb +19 -0
  49. data/lib/nrser/labs/lots/parser.rb +21 -1
  50. data/lib/nrser/labs/stash.rb +4 -4
  51. data/lib/nrser/log.rb +25 -21
  52. data/lib/nrser/log/appender/sync.rb +15 -11
  53. data/lib/nrser/log/formatters/color.rb +0 -3
  54. data/lib/nrser/log/formatters/mixin.rb +4 -4
  55. data/lib/nrser/log/logger.rb +54 -6
  56. data/lib/nrser/log/mixin.rb +2 -1
  57. data/lib/nrser/log/plugin.rb +6 -6
  58. data/lib/nrser/log/types.rb +46 -29
  59. data/lib/nrser/mean_streak.rb +0 -8
  60. data/lib/nrser/mean_streak/document.rb +1 -4
  61. data/lib/nrser/message.rb +3 -3
  62. data/lib/nrser/meta/README.md +4 -0
  63. data/lib/nrser/meta/lazy_attr.rb +2 -2
  64. data/lib/nrser/meta/source/location.rb +1 -1
  65. data/lib/nrser/props.rb +34 -3
  66. data/lib/nrser/props/class_methods.rb +2 -1
  67. data/lib/nrser/props/instance_methods.rb +9 -9
  68. data/lib/nrser/props/metadata.rb +4 -12
  69. data/lib/nrser/props/mutable/stash.rb +5 -2
  70. data/lib/nrser/props/prop.rb +10 -19
  71. data/lib/nrser/rspex.rb +1 -20
  72. data/lib/nrser/rspex/example_group/describe_attribute.rb +3 -0
  73. data/lib/nrser/rspex/example_group/describe_called_with.rb +9 -4
  74. data/lib/nrser/rspex/example_group/describe_case.rb +1 -0
  75. data/lib/nrser/rspex/example_group/describe_class.rb +2 -0
  76. data/lib/nrser/rspex/example_group/describe_group.rb +1 -1
  77. data/lib/nrser/rspex/example_group/describe_instance.rb +3 -1
  78. data/lib/nrser/rspex/example_group/describe_message.rb +1 -1
  79. data/lib/nrser/rspex/example_group/describe_method.rb +64 -30
  80. data/lib/nrser/rspex/example_group/describe_response_to.rb +1 -1
  81. data/lib/nrser/rspex/example_group/describe_section.rb +4 -1
  82. data/lib/nrser/rspex/example_group/describe_sent_to.rb +1 -1
  83. data/lib/nrser/rspex/example_group/describe_setup.rb +1 -0
  84. data/lib/nrser/rspex/example_group/describe_source_file.rb +1 -1
  85. data/lib/nrser/rspex/example_group/describe_spec_file.rb +4 -2
  86. data/lib/nrser/rspex/example_group/describe_when.rb +2 -1
  87. data/lib/nrser/rspex/example_group/describe_x.rb +5 -5
  88. data/lib/nrser/rspex/format.rb +0 -15
  89. data/lib/nrser/sugar/method_missing_forwarder.rb +3 -3
  90. data/lib/nrser/sys/env/path.rb +2 -28
  91. data/lib/nrser/types.rb +63 -12
  92. data/lib/nrser/types/README.md +76 -0
  93. data/lib/nrser/types/arrays.rb +192 -137
  94. data/lib/nrser/types/attributes.rb +269 -0
  95. data/lib/nrser/types/booleans.rb +134 -83
  96. data/lib/nrser/types/bounded.rb +110 -47
  97. data/lib/nrser/types/collections.rb +119 -0
  98. data/lib/nrser/types/combinators.rb +283 -196
  99. data/lib/nrser/types/doc/display_table.md +66 -0
  100. data/lib/nrser/types/eqiuvalent.rb +91 -0
  101. data/lib/nrser/types/errors/check_error.rb +5 -11
  102. data/lib/nrser/types/errors/from_string_error.rb +3 -3
  103. data/lib/nrser/types/factory.rb +287 -20
  104. data/lib/nrser/types/hashes.rb +227 -179
  105. data/lib/nrser/types/in.rb +73 -36
  106. data/lib/nrser/types/is.rb +67 -60
  107. data/lib/nrser/types/is_a.rb +141 -84
  108. data/lib/nrser/types/labels.rb +45 -16
  109. data/lib/nrser/types/maybe.rb +6 -3
  110. data/lib/nrser/types/nil.rb +64 -27
  111. data/lib/nrser/types/not.rb +92 -34
  112. data/lib/nrser/types/numbers.rb +224 -169
  113. data/lib/nrser/types/pairs.rb +113 -89
  114. data/lib/nrser/types/paths.rb +250 -137
  115. data/lib/nrser/types/responds.rb +167 -89
  116. data/lib/nrser/types/selector.rb +234 -0
  117. data/lib/nrser/types/shape.rb +136 -65
  118. data/lib/nrser/types/strings.rb +189 -63
  119. data/lib/nrser/types/symbols.rb +83 -33
  120. data/lib/nrser/types/top.rb +89 -0
  121. data/lib/nrser/types/tuples.rb +134 -98
  122. data/lib/nrser/types/type.rb +617 -505
  123. data/lib/nrser/types/when.rb +123 -98
  124. data/lib/nrser/types/where.rb +182 -91
  125. data/lib/nrser/version.rb +1 -1
  126. data/spec/lib/nrser/core_ext/pathname/subpath_spec.rb +22 -0
  127. data/spec/lib/nrser/errors/attr_error_spec.rb +68 -0
  128. data/spec/lib/nrser/errors/count_error_spec.rb +69 -0
  129. data/spec/lib/nrser/functions/path/normalize_path_spec.rb +35 -0
  130. data/spec/lib/nrser/functions/tree/map_tree_spec.rb +74 -96
  131. data/spec/lib/nrser/functions/tree/transform_spec.rb +11 -11
  132. data/spec/lib/nrser/labs/config_spec.rb +22 -0
  133. data/spec/lib/nrser/labs/i8/struct_spec.rb +39 -0
  134. data/spec/lib/nrser/types/display_spec.rb +50 -0
  135. data/spec/lib/nrser/types/paths_spec.rb +16 -10
  136. data/spec/lib/nrser/types/selector_spec.rb +125 -0
  137. data/spec/spec_helper.rb +4 -5
  138. metadata +105 -22
  139. data/lib/nrser/types/any.rb +0 -41
  140. data/lib/nrser/types/attrs.rb +0 -213
  141. data/lib/nrser/types/trees.rb +0 -42
@@ -1,109 +1,133 @@
1
- # Requirements
2
- # =======================================================================
3
-
4
- # Stdlib
5
- # -----------------------------------------------------------------------
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
6
3
 
7
- # Deps
8
- # -----------------------------------------------------------------------
4
+ # Requirements
5
+ # ========================================================================
9
6
 
10
7
  # Project / Package
11
- # -----------------------------------------------------------------------
8
+ # ------------------------------------------------------------------------
9
+
12
10
  require 'nrser/core_ext/hash'
13
11
 
14
12
  require_relative './combinators'
13
+ require_relative './attributes'
15
14
  require_relative './tuples'
16
15
 
17
16
 
18
- # Refinements
19
- # =======================================================================
17
+ # Namespace
18
+ # ========================================================================
20
19
 
20
+ module NRSER
21
+ module Types
21
22
 
22
- # Declarations
23
+
24
+ # Definitions
23
25
  # =======================================================================
24
26
 
25
- module NRSER; end
27
+ # @!group Pairs Type Factories
28
+ # ----------------------------------------------------------------------------
26
29
 
27
30
 
28
- # Definitions
29
- # =======================================================================
31
+ #@!method self.ArrayPair key: self.Top, value: self.Top, **options
32
+ # Type for key/value pairs encoded as a {.Tuple} ({::Array}) of length 2.
33
+ #
34
+ # @param [TYPE] key
35
+ # Key type. Made into a type by {NRSER::Types.make} if it's not already.
36
+ #
37
+ # @param [TYPE] value
38
+ # Value type. Made into a type by {NRSER::Types.make} if it's not already.
39
+ #
40
+ # @param [Hash] options
41
+ # Passed to {Type#initialize}.
42
+ #
43
+ # @return [Type]
44
+ #
45
+ def_type :ArrayPair,
46
+ default_name: false,
47
+ parameterize: [ :key, :value ],
48
+ &->( key: self.Top, value: self.Top, **options ) do
49
+ tuple \
50
+ key,
51
+ value,
52
+ **options
53
+ end # .ArrayPair
30
54
 
31
- module NRSER::Types
32
-
33
- # Type for key/value pairs encoded as a {.tuple} (Array) of length 2.
34
- #
35
- def_factory(
36
- :array_pair,
37
- ) do |name: 'ArrayPair', key: any, value: any, **options|
38
- unless options.key? :name
39
- options[:name] = if key == any && value == any
40
- 'ArrayPair'
41
- else
42
- key = NRSER::Types.make key
43
- value = NRSER::Types.make value
44
-
45
- "ArrayPair<#{ key.name }, #{ value.name }>"
46
- end
47
- end
48
-
49
- tuple \
50
- key,
51
- value,
52
- # name: name,
53
- **options
54
- end # .array_pair
55
-
55
+
56
+ # @!method self.HashPair key: self.Top, value: self.Top, **options
57
+ #
58
+ # Type whose members are single a key/value pairs encoded as {::Hash} instances
59
+ # with a single entry (`::Hash#length==1`).
60
+ #
61
+ # @param [TYPE] key
62
+ # Key type. Made into a type by {NRSER::Types.make} if it's not already.
63
+ #
64
+ # @param [TYPE] value
65
+ # Value type. Made into a type by {NRSER::Types.make} if it's not already.
66
+ #
67
+ # @param [Hash] options
68
+ # Passed to {Type#initialize}.
69
+ #
70
+ # @return [Type]
71
+ #
72
+ def_type :HashPair,
73
+ default_name: false,
74
+ parameterize: [ :key, :value ],
75
+ &->( key: self.Top, value: self.Top, **options ) do
76
+ key = self.make key
77
+ value = self.make value
78
+
79
+ options[:name] ||= "Hash<(#{ key.name }, #{ value.name })>"
56
80
 
57
- # Type for key/value pairs encoded as {Hash} with a single entry.
58
- #
59
- # @param [String] name:
60
- # Name to give the new type.
61
- #
62
- # @param [Hash] **options
63
- # Other options to pass to
64
- #
65
- def_factory(
66
- :hash_pair,
67
- ) do |key: any, value: any, **options|
68
- unless options.key? :name
69
- options[:name] = if key == any && value == any
70
- 'HashPair'
71
- else
72
- key = NRSER::Types.make key
73
- value = NRSER::Types.make value
74
-
75
- "HashPair<#{ key.name }, #{ value.name }>"
76
- end
77
- end
78
-
79
- intersection \
80
- hash_type( keys: key, values: value ),
81
- length( 1 ),
82
- # name: name,
83
- **options
84
- end # .hash_pair
81
+ options[:symbolic] ||= "(#{ key.symbolic }=>#{ value.symbolic })"
85
82
 
83
+ intersection \
84
+ self.Hash( keys: key, values: value ),
85
+ self.Length( 1 ),
86
+ **options
87
+ end # .HashPair
88
+
89
+
90
+ #@!method self.Pair key: self.Top, value: self.Top, **options
91
+ # A key/value pair, which can be encoded as an Array of length 2 or a
92
+ # Hash of length 1.
93
+ #
94
+ # @param [TYPE] key
95
+ # Key type. Made into a type by {NRSER::Types.make} if it's not already.
96
+ #
97
+ # @param [TYPE] value
98
+ # Value type. Made into a type by {NRSER::Types.make} if it's not already.
99
+ #
100
+ # @param [Hash] options
101
+ # Passed to {Type#initialize}.
102
+ #
103
+ # @return [Type]
104
+ #
105
+ def_type :Pair,
106
+ default_name: false,
107
+ parameterize: [ :key, :value ],
108
+ &->( key: self.Top, value: self.Top, **options ) do
109
+ key = self.make key
110
+ value = self.make value
86
111
 
87
- # A key/value pair, which can be encoded as an Array of length 2 or a
88
- # Hash of length 1.
89
- #
90
- #
91
- def_factory :pair do |key: any, value: any, **options|
92
- unless options.key? :name
93
- options[:name] = if key == any && value == any
94
- 'Pair'
95
- else
96
- key = NRSER::Types.make key
97
- value = NRSER::Types.make value
98
-
99
- "Pair<#{ key.name }, #{ value.name }>"
100
- end
101
- end
102
-
103
- union \
104
- array_pair( key: key, value: value ),
105
- hash_pair( key: key, value: value ),
106
- **options
107
- end # #pair
112
+ options[:name] ||= if key == self.Top && value == self.Top
113
+ "Pair"
114
+ else
115
+ "Pair<#{ key.name }, #{ value.name }>"
116
+ end
117
+
118
+ options[:symbolic] ||= "(#{ key.symbolic }, #{ value.symbolic })"
108
119
 
109
- end # module NRSER::Types
120
+ union \
121
+ self.ArrayPair( key: key, value: value ),
122
+ self.HashPair( key: key, value: value ),
123
+ **options
124
+ end # .Pair
125
+
126
+ # @!endgroup Pairs Type Factories # ******************************************
127
+
128
+
129
+ # /Namespace
130
+ # ========================================================================
131
+
132
+ end # module NRSER
133
+ end #module Types
@@ -1,153 +1,266 @@
1
1
  # Requirements
2
2
  # =======================================================================
3
3
 
4
- # Stdlib
5
- # -----------------------------------------------------------------------
6
-
7
- # Deps
8
- # -----------------------------------------------------------------------
9
-
10
4
  # Project / Package
11
5
  # -----------------------------------------------------------------------
12
6
 
13
7
  require 'nrser/core_ext/pathname'
8
+ require 'nrser/functions/path/normalized'
14
9
 
15
10
  require_relative './is_a'
16
11
  require_relative './where'
17
12
  require_relative './combinators'
18
13
 
19
14
 
15
+ # Namespace
16
+ # ========================================================================
17
+
18
+ module NRSER
19
+ module Types
20
+
21
+
20
22
  # Definitions
21
23
  # =======================================================================
22
24
 
23
- module NRSER::Types
24
-
25
- # @!group Type Factory Functions
26
-
27
- def_factory :pathname do |to_data: :to_s, **options|
28
- is_a \
29
- Pathname,
30
- from_s: ->( string ) { Pathname.new string },
31
- to_data: to_data,
32
- **options
33
- end
34
-
35
-
36
- # A type satisfied by a {Pathname} instance that's not empty (meaning it's
37
- # string representation is not empty).
38
- def_factory :non_empty_pathname do |name: 'NonEmptyPathname', **options|
39
- all_of \
40
- pathname,
41
- attrs( to_s: non_empty_str ),
42
- name: name,
43
- **options
44
- end
45
-
46
-
47
- # @!method
48
- # A path is a non-empty {String} or {Pathname}.
49
- #
50
- # @param **options see NRSER::Types::Type#initialize
51
- #
52
- # @return [NRSER::Types::Type]
53
- #
54
- def_factory :path do |name: 'Path', **options|
55
- one_of \
56
- non_empty_str,
57
- non_empty_pathname,
58
- name: name,
59
- **options
60
- end # #path
61
-
62
-
63
- def_factory :posix_path_segment,
64
- aliases: [:path_segment, :path_seg] \
65
- do |name: 'POSIXPathSegment', **options|
66
- all_of \
67
- non_empty_str,
68
- respond( to: [:include?, '/'], with: false ),
69
- name: name,
70
- **options
71
- end
72
-
73
-
74
- # An absolute {#path}.
75
- #
76
- # @param **options see NRSER::Types::Type#initialize
77
- #
78
- def_factory :abs_path do |name: 'AbsPath', **options|
79
- intersection \
80
- path,
81
- # Weirdly, there is no {File.absolute?}..
82
- attrs( to_pn: attrs( absolute?: true ) ),
83
- name: name,
84
- from_s: ->( s ) { File.expand_path s },
85
- **options
86
- end
87
-
88
-
89
- # A relative path.
90
- #
91
- # @todo
92
- # Quick addition, not sure if it's totally right with regard to tilde
93
- # paths and such.
94
- #
95
- def_factory :rel_path do |name: 'RelPath', **options|
96
- intersection \
97
- path,
98
- ~abs_path,
99
- name: name,
100
- **options
101
- end
102
-
103
-
104
- # A {NRSER::Types.path} that is a directory.
105
- #
106
- # @param [Hash] **options
107
- # Construction options passed to {NRSER::Types::Type#initialize}.
108
- #
109
- # @return [NRSER::Types::Type]
110
- #
111
- def_factory :dir_path do |name: 'DirPath', **options|
112
- intersection \
113
- path,
114
- # TODO How to change this from {.where}?
115
- where { |path| File.directory? path },
116
- name: name,
117
- **options
118
- end # #dir_path
119
-
120
-
121
- # Absolute {.path} to a directory (both an {.abs_path} and an {.dir_path}).
122
- #
123
- # @param name: (see NRSER::Types::Type#initialize)
124
- #
125
- # @param **options
126
- # See {NRSER::Types::Type#initialize}
127
- #
128
- def_factory :abs_dir_path do |name: 'AbsDirPath', **options|
129
- intersection \
130
- abs_path,
131
- dir_path,
132
- name: name,
133
- **options
134
- end # .abs_dir_path
135
-
136
-
137
- # A {.path} that is a file (using {File.file?} to test).
138
- #
139
- # @param name: (see NRSER::Types::Type#initialize)
140
- #
141
- # @param **options
142
- # See {NRSER::Types::Type#initialize}
143
- #
144
- def_factory :file_path do |name: 'FilePath', **options|
145
- intersection \
146
- path,
147
- # TODO How to change this from {.where}?
148
- where { |path| File.file? path },
149
- name: name,
150
- **options
151
- end
152
-
153
- end # module NRSER::Types
25
+ # Constants
26
+ # ----------------------------------------------------------------------------
27
+
28
+ # Regular expression to match "tilde" user-home-relative paths.
29
+ #
30
+ # @return [Regexp]
31
+ #
32
+ TILDE_PATH_RE = /\A\~(?:\/|\z)/
33
+
34
+
35
+ # @!group Path Type Factories
36
+ # ----------------------------------------------------------------------------
37
+
38
+ #@!method self.Pathname **options
39
+ # Just a type for instances of {Pathname}.
40
+ #
41
+ # @param [Hash] options
42
+ # Passed to {Type#initialize}.
43
+ #
44
+ # @return [Type]
45
+ #
46
+ def_type :Pathname,
47
+ to_data: :to_s,
48
+ from_s: ->( string ) { Pathname.new string } \
49
+ do |**options|
50
+ is_a Pathname, **options
51
+ end
52
+
53
+
54
+ #@!method self.NonEmptyPathname **options
55
+ # A {.Pathname} that isn't empty. Because not emptiness is often important.
56
+ #
57
+ # @param [Hash] options
58
+ # Passed to {Type#initialize}.
59
+ #
60
+ # @return [Type]
61
+ #
62
+ def_type :NonEmptyPathname,
63
+ &->( **options ) do
64
+ self.Intersection \
65
+ self.Pathname,
66
+ self.Attributes( to_s: self.NonEmptyString ),
67
+ **options
68
+ end # .NonEmptyPathname
69
+
70
+
71
+ # @!method self.Path **options
72
+ # A path is a {.NonEmptyString} or {.NonEmptyPathname}.
73
+ #
74
+ # @param [Hash] options
75
+ # See {Type#initialize}.
76
+ #
77
+ # @return [Type]
78
+ #
79
+ def_type :Path,
80
+ &->( **options ) do
81
+ self.Union \
82
+ self.NonEmptyString,
83
+ self.NonEmptyPathname,
84
+ **options
85
+ end # #Path
86
+
87
+
88
+ #@!method self.POSIXPathSegment **options
89
+ # A POSIX path segment (directory, file name) - any {.NonEmptyString} that
90
+ # doesn't have `/` in it.
91
+ #
92
+ # @param [Hash] options
93
+ # Passed to {Type#initialize}.
94
+ #
95
+ # @return [Type]
96
+ #
97
+ def_type :POSIXPathSegment,
98
+ aliases: [ :path_segment, :path_seg ],
99
+ &->( **options ) do
100
+ self.Intersection \
101
+ self.NonEmptyString,
102
+ self.Respond( to: [:include?, '/'], with: false ),
103
+ **options
104
+ end # .POSIXPathSegment
105
+
106
+
107
+ # @!method self.AbsolutePath **options
108
+ # An absolute {.Path}.
109
+ #
110
+ # @param [Hash] options
111
+ # Passed to {Type#initialize}.
112
+ #
113
+ # @return [Type]
114
+ #
115
+ def_type :AbsolutePath,
116
+ aliases: [ :AbsPath, :abs_path ],
117
+ # TODO IDK how I feel about this...
118
+ # from_s: ->( s ) { File.expand_path s },
119
+ &->( **options ) do
120
+ self.Intersection \
121
+ self.Path,
122
+ # Weirdly, there is no {File.absolute?}..
123
+ self.Attributes( to_pn: attrs( absolute?: true ) ),
124
+ **options
125
+ end # .AbsolutePath
126
+
127
+
128
+ #@!method self.HomePath **options
129
+ # A path that starts with `~`, meaning it's relative to a user's home
130
+ # directory (to Ruby, see note below).
131
+ #
132
+ # > ### Note: How Bash and Ruby Think Differently About Home Paths ###
133
+ # >
134
+ # > #### Ruby Always Tries to Go Home ####
135
+ # >
136
+ # > From my understanding and fiddling around Ruby considers *any* path that
137
+ # > starts with `~` a "home path" for the purpose of expanding, such as in
138
+ # > {::File.expand_path} and {::Pathname#expand_path}.
139
+ # >
140
+ # > You can see this clearly in the [rb_file_expand_path_internal][] C
141
+ # > function, which is where those expand methods end up.
142
+ # >
143
+ # > [rb_file_expand_path_internal]: https://github.com/ruby/ruby/blob/61bef8612afae25b912627e69699ddbef81adf93/file.c#L3486
144
+ # >
145
+ # > #### Bash ####
146
+ # >
147
+ # > However
148
+ # >
149
+ # > However - Bash 4's `cd` - on MacOSX, at least - treats `~some_user` as
150
+ # > being a home directory *only if* `some_user` exists... and you may have
151
+ # > a file or directory in the working dir named `~some_user` that it will
152
+ # > correctly fall back on if `some_user` does not exist.
153
+ # >
154
+ # > Paths are complicated, man.
155
+ #
156
+ # @param [Hash] options
157
+ # Passed to {Type#initialize}.
158
+ #
159
+ # @return [Type]
160
+ #
161
+ def_type :HomePath,
162
+ &->( **options ) do
163
+ self.Intersection \
164
+ self.Path,
165
+ self.Respond( to: [ :start_with?, '~' ], with: self.True ),
166
+ **options
167
+ end # .HomePath
168
+
169
+
170
+ # @!method self.AbsPath **options
171
+ # A relative {.Path}, which is just a {.Path} that's not {.AbsPath} or
172
+ # {.TildePath}.
173
+ #
174
+ # @param [Hash] options
175
+ # Passed to {Type#initialize}.
176
+ #
177
+ # @return [Type]
178
+ #
179
+ def_type :RelPath,
180
+ &->( **options ) do
181
+ self.Intersection \
182
+ self.Path,
183
+ !self.AbsPath,
184
+ !self.TildePath,
185
+ **options
186
+ end
187
+
188
+
189
+ # @method self.DirPath **options
190
+ # A {.Path} that is a directory. Requires checking the file system.
191
+ #
192
+ # @param [Hash] options
193
+ # Passed to {Type#initialize}.
194
+ #
195
+ # @return [Type]
196
+ #
197
+ def_type :DirPath,
198
+ &->( **options ) do
199
+ self.Intersection \
200
+ self.Path,
201
+ self.Where( File.method :directory? ),
202
+ **options
203
+ end # .DirPath
204
+
205
+
206
+ # @!method self.AbsDirPath **options
207
+ # Absolute {.Path} to a directory (both an {.AbsPath} and an {.DirPath}).
208
+ #
209
+ # @param [Hash] options
210
+ # Passed to {Type#initialize}.
211
+ #
212
+ # @return [Type]
213
+ #
214
+ def_type :AbsDirPath,
215
+ &->( **options ) do
216
+ self.Intersection \
217
+ self.AbsPath,
218
+ self.DirPath,
219
+ **options
220
+ end # .AbsDirPath
221
+
222
+
223
+ # @!method self.FilePath **options
224
+ # A {.Path} that is a file (using {File.file?} to test).
225
+ #
226
+ # @param name: (see NRSER::Types::Type#initialize)
227
+ #
228
+ # @param [Hash] options
229
+ # See {NRSER::Types::Type#initialize}
230
+ #
231
+ def_type :FilePath,
232
+ &->( **options ) do
233
+ self.Intersection \
234
+ self.Path,
235
+ self.Where( File.method :file? ),
236
+ **options
237
+ end # .FilePath
238
+
239
+
240
+ #@!method self.NormalizedPath **options
241
+ # @todo Document NormalizedPath type factory.
242
+ #
243
+ # @param [Hash] options
244
+ # Passed to {Type#initialize}.
245
+ #
246
+ # @return [Type]
247
+ #
248
+ def_type :NormalizedPath,
249
+ aliases: [ :NormPath, :norm_path ],
250
+ &->( **options ) do
251
+ self.Intersection \
252
+ self.Path,
253
+ self.Where( NRSER.method :normalized_path? ),
254
+ **options
255
+ end # .NormalizedPath
256
+
257
+
258
+
259
+ # @!endgroup Path Type Factories # *******************************************
260
+
261
+
262
+ # /Namespace
263
+ # ========================================================================
264
+
265
+ end # module Types
266
+ end # module NRSER