| 51 | } |
| 52 | |
| 53 | String PatternedNameGenerator::processRule(JsonArray const& rule, RandomSource& random) const { |
| 54 | if (rule.empty()) |
| 55 | return ""; |
| 56 | Json meta; |
| 57 | String result; |
| 58 | String mode = "alts"; |
| 59 | size_t index = 0; |
| 60 | bool titleCase = false; |
| 61 | if (rule[0].type() == Json::Type::Object) { |
| 62 | meta = rule[0]; |
| 63 | mode = meta.getString("mode", mode); |
| 64 | titleCase = meta.getBool("titleCase", false); |
| 65 | index++; |
| 66 | } |
| 67 | |
| 68 | if (mode == "serie") { |
| 69 | for (; index < rule.size(); index++) { |
| 70 | auto entry = rule[index]; |
| 71 | if (entry.type() == Json::Type::Array) |
| 72 | result += processRule(entry.toArray(), random); |
| 73 | else |
| 74 | result += entry.toString(); |
| 75 | } |
| 76 | } else if (mode == "alts") { |
| 77 | int i = index + random.randInt(rule.size() - 1 - index); |
| 78 | auto entry = rule[i]; |
| 79 | if (entry.type() == Json::Type::Array) |
| 80 | result += processRule(entry.toArray(), random); |
| 81 | else |
| 82 | result += entry.toString(); |
| 83 | } else if (mode == "markov") { |
| 84 | if (!m_markovSources.contains(meta.getString("source"))) |
| 85 | throw NameGeneratorException::format("Unknown name source '{}'", meta.getString("source")); |
| 86 | |
| 87 | auto source = m_markovSources.get(meta.getString("source")); |
| 88 | auto lengthRange = meta.getArray("targetLength"); |
| 89 | auto targetLength = random.randUInt(lengthRange[0].toUInt(), lengthRange[1].toUInt()); |
| 90 | |
| 91 | size_t tries = 0; |
| 92 | String piece; |
| 93 | do { |
| 94 | ++tries; |
| 95 | piece = random.randFrom(source.starts); |
| 96 | while (piece.length() < targetLength |
| 97 | || !source.ends.contains(piece.slice(piece.length() - source.endSize, piece.length()))) { |
| 98 | String link = piece.slice(piece.length() - source.prefixSize, piece.length()); |
| 99 | if (!source.chains.contains(link)) |
| 100 | break; |
| 101 | piece += random.randFrom(source.chains.get(link)); |
| 102 | } |
| 103 | } while (piece.length() > lengthRange[1].toUInt() && tries < 10); |
| 104 | |
| 105 | result += piece; |
| 106 | } else |
| 107 | throw StarException::format("Unknown mode: {}", mode); |
| 108 | |
| 109 | if (titleCase) |
| 110 | result = result.titleCase(); |
nothing calls this directly
no test coverage detected