@@ -36,8 +36,6 @@ object patterns {
36
36
* @define atomicNonTerminal
37
37
* when this parser is not to be considered as a terminal error, use `atomic` around the ''entire'' combinator to
38
38
* allow for backtracking if this parser succeeds (and therefore fails).
39
- *
40
- * @define Ensures this parser does not succeed, failing with a
41
39
*/
42
40
implicit final class VerifiedErrors [P , A ](p : P )(implicit con : P => Parsley [A ]) {
43
41
/** Ensures this parser does not succeed, failing with a specialised error based on this parsers result if it does.
@@ -117,7 +115,7 @@ object patterns {
117
115
* the given `errGen` with width the same as the parsed data. However, if this parser fails, no input is consumed
118
116
* and an empty error is generated. This parser will produce no labels if it fails.
119
117
*
120
- * @param err
118
+ * @param err the generator that produces the error message.
121
119
* @since 4.4.0
122
120
* @note $autoAmend
123
121
* @note $atomicNonTerminal
@@ -134,20 +132,102 @@ object patterns {
134
132
@ inline private def verifiedWithVanillaRaw (reasonGen : A => Option [String ]) = verifiedWithVanilla(_ => VanillaGen .RawItem , reasonGen)
135
133
}
136
134
137
- // TODO: document!
135
+ /** This class exposes combinators related to the ''Preventative Errors'' parser design pattern.
136
+ *
137
+ * This extension class operates on values that are convertible to parsers. The combinators it enables
138
+ * allow for the parsing of known illegal values, providing richer error messages in case they succeed.
139
+ *
140
+ * @constructor This constructor should not be called manually, it is designed to be used via Scala's implicit resolution.
141
+ * @param p the value that this class is enabling methods on.
142
+ * @param con a conversion that allows values convertible to parsers to be used.
143
+ * @tparam P the type of base value that this class is used on (the conversion to `Parsley`) is summoned automatically.
144
+ * @since 4.4.0
145
+ *
146
+ * @define autoAmend
147
+ * when this combinator fails (and not this parser itself), it will generate errors rooted at the start of the
148
+ * parse (as if [[parsley.errors.combinator$.amend `amend` ]] had been used) and the caret will span the entire
149
+ * successful parse of this parser.
150
+ *
151
+ * @define atomicNonTerminal
152
+ * when this parser is not to be considered as a terminal error, use `atomic` around the ''entire'' combinator to
153
+ * allow for backtracking if this parser succeeds (and therefore fails).
154
+ */
138
155
implicit final class PreventativeErrors [P , A ](p : P )(implicit con : P => Parsley [A ]) {
139
- // TODO: document and test
156
+ // TODO: test
157
+ /** Ensures this parser does not succeed, failing with a specialised error based on this parsers result if it does.
158
+ *
159
+ * If this parser succeeds, input is consumed and this combinator will fail, producing an error message
160
+ * based on the parsed result. However, if this parser fails, no input is consumed and this combinator succeeds.
161
+ * This parser will produce no evidence of running if it succeeds.
162
+ *
163
+ * @param msggen the function that generates the error messages from the parsed value.
164
+ * @since 4.4.0
165
+ * @note $autoAmend
166
+ * @note $atomicNonTerminal
167
+ */
140
168
def preventativeFail (msggen : A => Seq [String ]): Parsley [Unit ] = this .preventWith(new SpecialisedGen [A ] {
141
169
override def messages (x : A ) = msggen(x)
142
170
})
143
- // TODO: document and test
171
+
172
+ // TODO: test
173
+ /** Ensures this parser does not succeed, failing with a fixed specialised error if it does.
174
+ *
175
+ * If this parser succeeds, input is consumed and this combinator will fail, producing an error message with the
176
+ * given messages. However, if this parser fails, no input is consumed and this combinator succeeds.
177
+ * This parser will produce no evidence of running if it succeeds.
178
+ *
179
+ * @param msg0 the first message in the error message.
180
+ * @param msgs the remaining messages that will make up the error message.
181
+ * @since 4.4.0
182
+ * @note $autoAmend
183
+ * @note $atomicNonTerminal
184
+ */
144
185
def preventativeFail (msg0 : String , msgs : String * ): Parsley [Unit ] = this .preventativeFail(_ => msg0 +: msgs)
145
- // TODO: document and test
186
+
187
+ // TODO: test
188
+ /** Ensures this parser does not succeed, failing with a vanilla error with an unexpected message and caret spanning the parse and a reason generated
189
+ * from this parser's result.
190
+ *
191
+ * If this parser succeeds, input is consumed and this combinator will fail, producing an unexpected message the same width as
192
+ * the parse along with a reason generated from the successful parse along with the given labels. However, if this parser fails, no input is
193
+ * consumed and this combinator succeeds. This parser will produce no evidence of running if it succeeds.
194
+ *
195
+ * @param reason a function that produces a reason for the error given the parsed result.
196
+ * @param labels the labels that should be expected if this parser hadn't succeeded.
197
+ * @since 4.4.0
198
+ * @note $autoAmend
199
+ * @note $atomicNonTerminal
200
+ */
146
201
def preventativeExplain (reason : A => String , labels : String * ): Parsley [Unit ] = this .preventWithVanillaRaw(x => Some (reason(x)), labels : _* )
147
- // TODO: document and test
202
+
203
+ // TODO: test
204
+ /** Ensures this parser does not succeed, failing with a vanilla error with an unexpected message and caret spanning the parse and a given reason.
205
+ *
206
+ * If this parser succeeds, input is consumed and this combinator will fail, producing an unexpected message the same width as
207
+ * the parse along with the given reason and given labels. However, if this parser fails, no input is consumed and this combinator succeeds.
208
+ * This parser will produce no evidence of running if it succeeds.
209
+ *
210
+ * @param reason the reason that this parser is illegal.
211
+ * @param labels the labels that should be expected if this parser hadn't succeeded.
212
+ * @since 4.4.0
213
+ * @note $autoAmend
214
+ * @note $atomicNonTerminal
215
+ */
148
216
def preventativeExplain (reason : String , labels : String * ): Parsley [Unit ] = this .preventativeExplain(_ => reason, labels : _* )
149
217
150
- // TODO: document and test
218
+ // TODO: test
219
+ /** Ensures this parser does not succeed, failing with an error as described by the given `ErrorGen` object.
220
+ *
221
+ * If this parser succeeds, input is consumed and this combinator will fail, producing an error message using
222
+ * the given `errGen` with width the same as the parsed data along with the given labels. However, if this parser
223
+ * fails, no input is consumed and this combinator succeeds. This parser will produce no evidence of running if it succeeds.
224
+ *
225
+ * @param err the generator that produces the error message.
226
+ * @param labels the labels that should be expected if this parser hadn't succeeded.
227
+ * @since 4.4.0
228
+ * @note $autoAmend
229
+ * @note $atomicNonTerminal
230
+ */
151
231
def preventWith (err : ErrorGen [A ], labels : String * ) = {
152
232
val inner : Parsley [Either [(A , Int ), Unit ]] = withWidth(atomic(con(p)).newHide) <+> unit
153
233
val labelledErr = labels match {
0 commit comments