Generate a valid [`Ident`] with the provided `prefix` and `suffix`. # Examples ``` use mz_sql_parser::ast::{Ident, IdentError}; let good_id = Ident::try_generate_name("hello", "_world", |_| Ok::<_, IdentError>(true)).unwrap(); assert_eq!(good_id.as_str(), "hello_world"); // Return invalid once. let mut attempts = 0; let one_failure = Ident::try_generate_name("hello", "_world", |_candidate| { i
(prefix: P, suffix: S, mut is_valid: F)
| 161 | /// assert_eq!(one_failure.as_str(), "hello_world_1"); |
| 162 | /// ``` |
| 163 | pub fn try_generate_name<P, S, F, E>(prefix: P, suffix: S, mut is_valid: F) -> Result<Self, E> |
| 164 | where |
| 165 | P: Into<String>, |
| 166 | S: Into<String>, |
| 167 | E: From<IdentError>, |
| 168 | F: FnMut(&Ident) -> Result<bool, E>, |
| 169 | { |
| 170 | const MAX_ATTEMPTS: usize = 1000; |
| 171 | |
| 172 | let prefix: String = prefix.into(); |
| 173 | let suffix: String = suffix.into(); |
| 174 | |
| 175 | // First just append the prefix and suffix. |
| 176 | let mut candidate = Ident(prefix.clone()); |
| 177 | candidate.append_lossy(suffix.clone()); |
| 178 | if is_valid(&candidate)? { |
| 179 | return Ok(candidate); |
| 180 | } |
| 181 | |
| 182 | // Otherwise, append a number to the back. |
| 183 | for i in 1..MAX_ATTEMPTS { |
| 184 | let mut candidate = Ident(prefix.clone()); |
| 185 | candidate.append_lossy(format!("{suffix}_{i}")); |
| 186 | |
| 187 | if is_valid(&candidate)? { |
| 188 | return Ok(candidate); |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | // Couldn't find any valid name! |
| 193 | Err(E::from(IdentError::FailedToGenerate { |
| 194 | prefix, |
| 195 | suffix, |
| 196 | attempts: MAX_ATTEMPTS, |
| 197 | })) |
| 198 | } |
| 199 | |
| 200 | /// Append the provided `suffix`, truncating `self` as necessary to satisfy our invariants. |
| 201 | /// |
nothing calls this directly
no test coverage detected