@@ -4958,6 +4958,74 @@ pub struct BuildError {
49584958 kind : BuildErrorKind ,
49594959}
49604960
4961+ #[ cfg( feature = "dfa-build" ) ]
4962+ impl BuildError {
4963+ /// Returns true if and only if this error corresponds to an error with DFA
4964+ /// construction that occurred because of exceeding a size limit.
4965+ ///
4966+ /// While this can occur when size limits like [`Config::dfa_size_limit`]
4967+ /// or [`Config::determinize_size_limit`] are exceeded, this can also occur
4968+ /// when the number of states or patterns exceeds a hard-coded maximum.
4969+ /// (Where these maximums are derived based on the values representable by
4970+ /// [`StateID`] and [`PatternID`].)
4971+ ///
4972+ /// This predicate is useful in contexts where you want to distinguish
4973+ /// between errors related to something provided by an end user (for
4974+ /// example, an invalid regex pattern) and errors related to configured
4975+ /// heuristics. For example, building a DFA might be an optimization that
4976+ /// you want to skip if construction fails because of an exceeded size
4977+ /// limit, but where you want to bubble up an error if it fails for some
4978+ /// other reason.
4979+ ///
4980+ /// # Example
4981+ ///
4982+ /// ```
4983+ /// # if cfg!(miri) { return Ok(()); } // miri takes too long
4984+ /// # if !cfg!(target_pointer_width = "64") { return Ok(()); } // see #1039
4985+ /// use regex_automata::{dfa::{dense, Automaton}, Input};
4986+ ///
4987+ /// let err = dense::Builder::new()
4988+ /// .configure(dense::Config::new()
4989+ /// .determinize_size_limit(Some(100_000))
4990+ /// )
4991+ /// .build(r"\w{20}")
4992+ /// .unwrap_err();
4993+ /// // This error occurs because a size limit was exceeded.
4994+ /// // But things are otherwise valid.
4995+ /// assert!(err.is_size_limit_exceeded());
4996+ ///
4997+ /// let err = dense::Builder::new()
4998+ /// .build(r"\bxyz\b")
4999+ /// .unwrap_err();
5000+ /// // This error occurs because a Unicode word boundary
5001+ /// // was used without enabling heuristic support for it.
5002+ /// // So... not related to size limits.
5003+ /// assert!(!err.is_size_limit_exceeded());
5004+ ///
5005+ /// let err = dense::Builder::new()
5006+ /// .build(r"(xyz")
5007+ /// .unwrap_err();
5008+ /// // This error occurs because the pattern is invalid.
5009+ /// // So... not related to size limits.
5010+ /// assert!(!err.is_size_limit_exceeded());
5011+ ///
5012+ /// # Ok::<(), Box<dyn std::error::Error>>(())
5013+ /// ```
5014+ #[ inline]
5015+ pub fn is_size_limit_exceeded ( & self ) -> bool {
5016+ use self :: BuildErrorKind :: * ;
5017+
5018+ match self . kind {
5019+ NFA ( _) | Unsupported ( _) => false ,
5020+ TooManyStates
5021+ | TooManyStartStates
5022+ | TooManyMatchPatternIDs
5023+ | DFAExceededSizeLimit { .. }
5024+ | DeterminizeExceededSizeLimit { .. } => true ,
5025+ }
5026+ }
5027+ }
5028+
49615029/// The kind of error that occurred during the construction of a DFA.
49625030///
49635031/// Note that this error is non-exhaustive. Adding new variants is not
0 commit comments