synthra 0.1.0

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 (302) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +4 -0
  3. data/.rubocop.yml +40 -0
  4. data/.yardopts +18 -0
  5. data/ACCESS_DOCS.md +116 -0
  6. data/ADVANCED_FEATURES_SUMMARY.md +245 -0
  7. data/CHANGELOG.md +498 -0
  8. data/CODE_OF_CONDUCT.md +122 -0
  9. data/CONTRIBUTING.md +307 -0
  10. data/DOCUMENTATION.md +204 -0
  11. data/DOCUMENTATION_GUIDE.md +194 -0
  12. data/LICENSE +22 -0
  13. data/README.md +1458 -0
  14. data/Rakefile +128 -0
  15. data/benchmark/README.md +591 -0
  16. data/benchmark/batch_generation.rb +63 -0
  17. data/benchmark/engine_comparison.rb +295 -0
  18. data/benchmark/single_record.rb +108 -0
  19. data/benchmark/streaming.rb +74 -0
  20. data/docs/ACTIVERECORD_INFERENCE.md +524 -0
  21. data/docs/API_SERVER.md +278 -0
  22. data/docs/CONFIG_FILE.md +315 -0
  23. data/docs/DATA_CONTRACTS.md +312 -0
  24. data/docs/ENHANCED_REPL.md +304 -0
  25. data/docs/FACTORY_BOT.md +271 -0
  26. data/docs/GITHUB_ACTION.md +420 -0
  27. data/docs/GRAPHQL_EXPORT.md +303 -0
  28. data/docs/GRAPHQL_FEDERATION.md +651 -0
  29. data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
  30. data/docs/LSP.md +189 -0
  31. data/docs/MIGRATION_GENERATOR.md +547 -0
  32. data/docs/MOCK_SERVER.md +280 -0
  33. data/docs/NATIVE_ENGINE.md +298 -0
  34. data/docs/OPENAPI_EXPORT.md +252 -0
  35. data/docs/PERFORMANCE_MODE.md +228 -0
  36. data/docs/PERSONAS.md +547 -0
  37. data/docs/PROPERTY_TESTING.md +284 -0
  38. data/docs/PROTOBUF_EXPORT.md +276 -0
  39. data/docs/QUALITY_METRICS.md +555 -0
  40. data/docs/QUICK_REFERENCE.md +88 -0
  41. data/docs/RAILS_ENGINE.md +404 -0
  42. data/docs/RAILS_INTEGRATION.md +454 -0
  43. data/docs/README.md +175 -0
  44. data/docs/REPL_QUICK_REFERENCE.md +149 -0
  45. data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
  46. data/docs/SCENARIOS.md +576 -0
  47. data/docs/SECURITY_TESTING.md +318 -0
  48. data/docs/SNAPSHOT_TESTING.md +308 -0
  49. data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
  50. data/docs/TERRAFORM_EXPORT.md +447 -0
  51. data/docs/TIME_TRAVEL.md +507 -0
  52. data/docs/USAGE_GUIDE.md +980 -0
  53. data/docs/WEBHOOK_SIMULATOR.md +579 -0
  54. data/docs/advanced_features.md +183 -0
  55. data/docs/api_reference.md +153 -0
  56. data/docs/behaviors.md +138 -0
  57. data/docs/best_practices.md +191 -0
  58. data/docs/dsl_reference.md +172 -0
  59. data/docs/examples.md +162 -0
  60. data/docs/generation_modes.md +125 -0
  61. data/docs/getting_started.md +92 -0
  62. data/docs/index.html +177 -0
  63. data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
  64. data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
  65. data/docs/troubleshooting.md +215 -0
  66. data/docs/type_reference.md +224 -0
  67. data/examples/hostile_mode_demo.rb +64 -0
  68. data/exe/synthra +6 -0
  69. data/ext/synthra_native/Cargo.lock +972 -0
  70. data/ext/synthra_native/Cargo.toml +46 -0
  71. data/ext/synthra_native/extconf.rb +41 -0
  72. data/ext/synthra_native/src/generator.rs +397 -0
  73. data/ext/synthra_native/src/lib.rs +229 -0
  74. data/ext/synthra_native/src/types.rs +1485 -0
  75. data/lib/generators/synthra/install_generator.rb +86 -0
  76. data/lib/generators/synthra/templates/api_response.dsl +15 -0
  77. data/lib/generators/synthra/templates/fake_data.rake +116 -0
  78. data/lib/generators/synthra/templates/synthra.yml +31 -0
  79. data/lib/generators/synthra/templates/synthra_support.rb +19 -0
  80. data/lib/generators/synthra/templates/user.dsl +11 -0
  81. data/lib/synthra/activerecord_inference.rb +394 -0
  82. data/lib/synthra/api.rb +381 -0
  83. data/lib/synthra/api_server.rb +718 -0
  84. data/lib/synthra/behaviors/applicator.rb +165 -0
  85. data/lib/synthra/behaviors/base.rb +155 -0
  86. data/lib/synthra/behaviors/close_connection.rb +60 -0
  87. data/lib/synthra/behaviors/deprecated.rb +100 -0
  88. data/lib/synthra/behaviors/failure.rb +69 -0
  89. data/lib/synthra/behaviors/latency.rb +103 -0
  90. data/lib/synthra/behaviors/partial_data.rb +83 -0
  91. data/lib/synthra/behaviors/randomize_order.rb +74 -0
  92. data/lib/synthra/behaviors/registry.rb +238 -0
  93. data/lib/synthra/behaviors/simulate_error.rb +79 -0
  94. data/lib/synthra/cli/commands/base.rb +105 -0
  95. data/lib/synthra/cli/commands/diff.rb +227 -0
  96. data/lib/synthra/cli/commands/docs.rb +67 -0
  97. data/lib/synthra/cli/commands/export.rb +150 -0
  98. data/lib/synthra/cli/commands/generate.rb +72 -0
  99. data/lib/synthra/cli/commands/import.rb +80 -0
  100. data/lib/synthra/cli/commands/lint.rb +53 -0
  101. data/lib/synthra/cli/commands/live.rb +57 -0
  102. data/lib/synthra/cli/commands/seed.rb +99 -0
  103. data/lib/synthra/cli/commands/validate.rb +28 -0
  104. data/lib/synthra/cli.rb +2471 -0
  105. data/lib/synthra/config_file.rb +129 -0
  106. data/lib/synthra/configuration.rb +281 -0
  107. data/lib/synthra/contracts_registry.rb +408 -0
  108. data/lib/synthra/database_seeder.rb +268 -0
  109. data/lib/synthra/deterministic_ids.rb +218 -0
  110. data/lib/synthra/documentation_generator.rb +414 -0
  111. data/lib/synthra/engine.rb +251 -0
  112. data/lib/synthra/errors.rb +1169 -0
  113. data/lib/synthra/export/base.rb +85 -0
  114. data/lib/synthra/export/csv.rb +101 -0
  115. data/lib/synthra/export/graphql.rb +266 -0
  116. data/lib/synthra/export/graphql_federation.rb +377 -0
  117. data/lib/synthra/export/graphviz.rb +258 -0
  118. data/lib/synthra/export/javascript.rb +327 -0
  119. data/lib/synthra/export/json_data.rb +61 -0
  120. data/lib/synthra/export/json_schema.rb +290 -0
  121. data/lib/synthra/export/openapi.rb +514 -0
  122. data/lib/synthra/export/protobuf.rb +483 -0
  123. data/lib/synthra/export/python.rb +560 -0
  124. data/lib/synthra/export/sql.rb +381 -0
  125. data/lib/synthra/export/sql_insert.rb +152 -0
  126. data/lib/synthra/export/terraform.rb +501 -0
  127. data/lib/synthra/export/type_mapping.rb +389 -0
  128. data/lib/synthra/export/typescript.rb +300 -0
  129. data/lib/synthra/export/xml_data.rb +104 -0
  130. data/lib/synthra/export/yaml_data.rb +56 -0
  131. data/lib/synthra/export.rb +404 -0
  132. data/lib/synthra/factory_bot_integration.rb +157 -0
  133. data/lib/synthra/field.rb +440 -0
  134. data/lib/synthra/functions/registry.rb +104 -0
  135. data/lib/synthra/generator/context.rb +372 -0
  136. data/lib/synthra/generator/engine.rb +336 -0
  137. data/lib/synthra/generator/faker_adapter.rb +425 -0
  138. data/lib/synthra/generator/modes.rb +444 -0
  139. data/lib/synthra/generator/resolver.rb +256 -0
  140. data/lib/synthra/generator/rng.rb +273 -0
  141. data/lib/synthra/generator/streamer.rb +63 -0
  142. data/lib/synthra/generator/uniqueness.rb +118 -0
  143. data/lib/synthra/initializer.rb +97 -0
  144. data/lib/synthra/limits.rb +279 -0
  145. data/lib/synthra/live_preview.rb +518 -0
  146. data/lib/synthra/loader_config.rb +78 -0
  147. data/lib/synthra/lsp/server.rb +689 -0
  148. data/lib/synthra/migration_generator.rb +301 -0
  149. data/lib/synthra/mixin.rb +174 -0
  150. data/lib/synthra/mock_server.rb +458 -0
  151. data/lib/synthra/native_engine.rb +304 -0
  152. data/lib/synthra/openapi_importer.rb +228 -0
  153. data/lib/synthra/output/json_formatter.rb +40 -0
  154. data/lib/synthra/output/ndjson_formatter.rb +55 -0
  155. data/lib/synthra/parser/ast.rb +1287 -0
  156. data/lib/synthra/parser/lexer.rb +1152 -0
  157. data/lib/synthra/parser/parser.rb +1664 -0
  158. data/lib/synthra/parser/tokens.rb +461 -0
  159. data/lib/synthra/performance_mode.rb +364 -0
  160. data/lib/synthra/personas.rb +397 -0
  161. data/lib/synthra/property_testing.rb +172 -0
  162. data/lib/synthra/quality_metrics.rb +405 -0
  163. data/lib/synthra/rails_test_helper.rb +248 -0
  164. data/lib/synthra/registry.rb +533 -0
  165. data/lib/synthra/relationships.rb +193 -0
  166. data/lib/synthra/repl/enhanced_repl.rb +607 -0
  167. data/lib/synthra/repl/formatter.rb +191 -0
  168. data/lib/synthra/scenarios.rb +423 -0
  169. data/lib/synthra/schema.rb +605 -0
  170. data/lib/synthra/schema_inheritance.rb +104 -0
  171. data/lib/synthra/schema_versioning.rb +212 -0
  172. data/lib/synthra/snapshot_testing.rb +199 -0
  173. data/lib/synthra/time_travel.rb +338 -0
  174. data/lib/synthra/type_definitions.rb +274 -0
  175. data/lib/synthra/types/address_location/addresses.rb +125 -0
  176. data/lib/synthra/types/address_location/airports.rb +200 -0
  177. data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
  178. data/lib/synthra/types/address_location/locations.rb +406 -0
  179. data/lib/synthra/types/base.rb +48 -0
  180. data/lib/synthra/types/commerce_products/commerce.rb +119 -0
  181. data/lib/synthra/types/commerce_products/companies.rb +71 -0
  182. data/lib/synthra/types/commerce_products/construction.rb +126 -0
  183. data/lib/synthra/types/commerce_products/products.rb +205 -0
  184. data/lib/synthra/types/core/collections.rb +513 -0
  185. data/lib/synthra/types/core/defaults.rb +76 -0
  186. data/lib/synthra/types/core/enums.rb +102 -0
  187. data/lib/synthra/types/core/identifiers.rb +445 -0
  188. data/lib/synthra/types/core/primitives.rb +586 -0
  189. data/lib/synthra/types/core/references.rb +466 -0
  190. data/lib/synthra/types/core/sequences.rb +304 -0
  191. data/lib/synthra/types/crypto/crypto.rb +162 -0
  192. data/lib/synthra/types/date_time/dates.rb +387 -0
  193. data/lib/synthra/types/finance_banking/banking.rb +424 -0
  194. data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
  195. data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
  196. data/lib/synthra/types/formula.rb +184 -0
  197. data/lib/synthra/types/health_medical/medical.rb +150 -0
  198. data/lib/synthra/types/hostile_payloads.rb +122 -0
  199. data/lib/synthra/types/json_array.rb +51 -0
  200. data/lib/synthra/types/media_entertainment/media.rb +62 -0
  201. data/lib/synthra/types/naughty_string.rb +30 -0
  202. data/lib/synthra/types/personal_names/chinese.rb +41 -0
  203. data/lib/synthra/types/personal_names/identifiers.rb +187 -0
  204. data/lib/synthra/types/personal_names/names.rb +246 -0
  205. data/lib/synthra/types/personal_names/national_id.rb +89 -0
  206. data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
  207. data/lib/synthra/types/regex.rb +248 -0
  208. data/lib/synthra/types/registry.rb +182 -0
  209. data/lib/synthra/types/repeating_element.rb +50 -0
  210. data/lib/synthra/types/scenario.rb +29 -0
  211. data/lib/synthra/types/technology_internet/apps.rb +67 -0
  212. data/lib/synthra/types/technology_internet/communication.rb +162 -0
  213. data/lib/synthra/types/technology_internet/devices.rb +80 -0
  214. data/lib/synthra/types/technology_internet/formats.rb +139 -0
  215. data/lib/synthra/types/technology_internet/networking.rb +143 -0
  216. data/lib/synthra/types/template.rb +92 -0
  217. data/lib/synthra/types/text_content/business.rb +128 -0
  218. data/lib/synthra/types/text_content/colors.rb +70 -0
  219. data/lib/synthra/types/text_content/misc.rb +237 -0
  220. data/lib/synthra/types/text_content/security.rb +130 -0
  221. data/lib/synthra/types/text_content/text_generation.rb +532 -0
  222. data/lib/synthra/types/travel/travel.rb +150 -0
  223. data/lib/synthra/utils/string_distance.rb +133 -0
  224. data/lib/synthra/validator/dsl_validator.rb +339 -0
  225. data/lib/synthra/validator/path_validator.rb +615 -0
  226. data/lib/synthra/version.rb +35 -0
  227. data/lib/synthra/webhook_simulator.rb +341 -0
  228. data/lib/synthra.rb +259 -0
  229. data/schemas/address.dsl +16 -0
  230. data/schemas/api_response.dsl +8 -0
  231. data/schemas/error_payload.dsl +9 -0
  232. data/schemas/order.dsl +10 -0
  233. data/schemas/order_item.dsl +8 -0
  234. data/schemas/payment.dsl +11 -0
  235. data/schemas/social_post.dsl +13 -0
  236. data/schemas/user.dsl +10 -0
  237. data/scripts/batch_fix_all.rb +96 -0
  238. data/scripts/delete_old_files.rb +32 -0
  239. data/scripts/fix_all_grouped_files.rb +137 -0
  240. data/scripts/fix_all_indentation.rb +48 -0
  241. data/scripts/fix_all_syntax.rb +124 -0
  242. data/scripts/fix_grouped_files.rb +184 -0
  243. data/scripts/fix_syntax_errors.rb +108 -0
  244. data/scripts/group_domain_types.rb +112 -0
  245. data/scripts/group_domain_types_fixed.rb +150 -0
  246. data/scripts/merge_domains_to_one_file.rb +68 -0
  247. data/scripts/move_existing_types.rb +130 -0
  248. data/scripts/split_grouped_types.rb +142 -0
  249. data/tech_docs/README.md +134 -0
  250. data/tech_docs/advanced/streaming.md +405 -0
  251. data/tech_docs/advanced/thread_safety.md +253 -0
  252. data/tech_docs/api/overview.md +485 -0
  253. data/tech_docs/appendices/type_chart.md +193 -0
  254. data/tech_docs/basic_concepts.md +383 -0
  255. data/tech_docs/behaviors/overview.md +346 -0
  256. data/tech_docs/dsl/complex_types.md +790 -0
  257. data/tech_docs/dsl/core_types.md +464 -0
  258. data/tech_docs/dsl/datetime_types.md +325 -0
  259. data/tech_docs/dsl/field_modifiers.md +414 -0
  260. data/tech_docs/dsl/grammar.md +431 -0
  261. data/tech_docs/dsl/schema_definition.md +399 -0
  262. data/tech_docs/export/README.md +276 -0
  263. data/tech_docs/installation.md +273 -0
  264. data/tech_docs/integration/ci_cd.md +707 -0
  265. data/tech_docs/integration/ci_cd_guide.md +579 -0
  266. data/tech_docs/integration/factory_bot.md +485 -0
  267. data/tech_docs/integration/rails.md +630 -0
  268. data/tech_docs/integration/rspec.md +449 -0
  269. data/tech_docs/modes/overview.md +350 -0
  270. data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
  271. data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
  272. data/tech_docs/quick_start.md +256 -0
  273. data/tech_docs/templates/README.md +805 -0
  274. data/tech_docs/tutorials/advanced.md +371 -0
  275. data/tech_docs/tutorials/getting_started.md +189 -0
  276. data/tech_docs/tutorials/intermediate.md +231 -0
  277. data/tech_docs/tutorials/template_gallery.md +569 -0
  278. data/tech_example/01_basic_usage.rb +238 -0
  279. data/tech_example/02_types_demo.rb +336 -0
  280. data/tech_example/04_cli_usage.md +429 -0
  281. data/tech_example/05_database_seeding.rb +283 -0
  282. data/tech_example/07_rspec_integration.rb +359 -0
  283. data/tech_example/10_custom_types.rb +387 -0
  284. data/tech_example/12_behaviors.rb +372 -0
  285. data/tech_example/13_twitter_dm_example.rb +120 -0
  286. data/tech_example/14_exact_json_structure.rb +253 -0
  287. data/tech_example/16_lsp_server.rb +56 -0
  288. data/tech_example/17_property_testing.rb +92 -0
  289. data/tech_example/18_enhanced_repl.rb +120 -0
  290. data/tech_example/19_security_fuzzing.rb +145 -0
  291. data/tech_example/NEW_FEATURES.md +169 -0
  292. data/tech_example/README.md +118 -0
  293. data/tech_example/schemas/api_response.dsl +123 -0
  294. data/tech_example/schemas/ecommerce.dsl +121 -0
  295. data/tech_example/schemas/twitter_dm.dsl +109 -0
  296. data/tech_example/schemas/user.dsl +36 -0
  297. data/vscode-extension/README.md +246 -0
  298. data/vscode-extension/language-configuration.json +31 -0
  299. data/vscode-extension/package.json +55 -0
  300. data/vscode-extension/snippets/fakedatadsl.json +198 -0
  301. data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
  302. metadata +478 -0
@@ -0,0 +1,229 @@
1
+ //! Synthra Native Extension
2
+ //!
3
+ //! High-performance data generation using Rust and fake-rs.
4
+ //! Provides 100-250x speedup over pure Ruby implementation.
5
+ //! Uses Rayon for parallel processing to utilize CPU cores.
6
+ //!
7
+ //! # Thread Control
8
+ //! Set `RAYON_NUM_THREADS` environment variable before loading the gem
9
+ //! to limit the number of threads used for parallel generation.
10
+ //! Example: `RAYON_NUM_THREADS=4 ruby my_script.rb`
11
+
12
+ use magnus::{function, prelude::*, Error, RArray, Ruby, Value};
13
+ use rayon::ThreadPoolBuilder;
14
+ use std::sync::atomic::{AtomicUsize, Ordering};
15
+
16
+ // Default thread count (2 threads to leave resources for other work)
17
+ const DEFAULT_THREADS: usize = 2;
18
+
19
+ // Track configured thread limit for reporting
20
+ static THREAD_LIMIT: AtomicUsize = AtomicUsize::new(DEFAULT_THREADS);
21
+
22
+ mod generator;
23
+ mod types;
24
+
25
+ /// Generate records and return as Ruby Array of Hashes
26
+ ///
27
+ /// # Arguments
28
+ /// * `schema_spec` - Array of [name, type_name, args_json, optional, nullable]
29
+ /// * `count` - Number of records to generate
30
+ /// * `seed` - Optional random seed for reproducibility
31
+ /// * `locale` - Locale string (en, fr_fr, de_de, etc.)
32
+ /// * `threads` - Number of threads (nil = default 2, 0 = use all cores)
33
+ fn generate(
34
+ ruby: &Ruby,
35
+ schema_spec: RArray,
36
+ count: usize,
37
+ seed: Option<u64>,
38
+ locale: Option<String>,
39
+ threads: Option<usize>,
40
+ ) -> Result<RArray, Error> {
41
+ // Configure thread pool
42
+ let num_threads = match threads {
43
+ Some(0) => num_cpus(), // 0 = use all cores
44
+ Some(t) => t.min(num_cpus()), // specified value
45
+ None => DEFAULT_THREADS, // default = 2
46
+ };
47
+
48
+ let _ = ThreadPoolBuilder::new()
49
+ .num_threads(num_threads)
50
+ .build_global();
51
+
52
+ let gen = generator::NativeGenerator::from_ruby(schema_spec, seed, locale)?;
53
+ gen.generate_to_ruby(ruby, count)
54
+ }
55
+
56
+ /// Generate records directly to a file (most efficient for large datasets)
57
+ ///
58
+ /// # Arguments
59
+ /// * `schema_spec` - Array of [name, type_name, args_json, optional, nullable]
60
+ /// * `count` - Number of records to generate
61
+ /// * `path` - Output file path
62
+ /// * `seed` - Optional random seed for reproducibility
63
+ /// * `locale` - Locale string
64
+ /// * `format` - Output format: "jsonl", "json", "csv"
65
+ /// * `threads` - Number of threads (nil = default 2, 0 = use all cores)
66
+ fn generate_to_file(
67
+ schema_spec: RArray,
68
+ count: usize,
69
+ path: String,
70
+ seed: Option<u64>,
71
+ locale: Option<String>,
72
+ format: Option<String>,
73
+ threads: Option<usize>,
74
+ ) -> Result<usize, Error> {
75
+ // Configure thread pool
76
+ let num_threads = match threads {
77
+ Some(0) => num_cpus(), // 0 = use all cores
78
+ Some(t) => t.min(num_cpus()), // specified value
79
+ None => DEFAULT_THREADS, // default = 2
80
+ };
81
+
82
+ let _ = ThreadPoolBuilder::new()
83
+ .num_threads(num_threads)
84
+ .build_global();
85
+
86
+ let gen = generator::NativeGenerator::from_ruby(schema_spec, seed, locale)?;
87
+ let fmt = format.as_deref().unwrap_or("jsonl");
88
+ gen.generate_to_file(count, &path, fmt)
89
+ .map_err(|e| Error::new(magnus::exception::runtime_error(), e.to_string()))
90
+ }
91
+
92
+ /// Generate a single record (for testing/preview)
93
+ fn generate_one(
94
+ ruby: &Ruby,
95
+ schema_spec: RArray,
96
+ seed: Option<u64>,
97
+ locale: Option<String>,
98
+ ) -> Result<Value, Error> {
99
+ let gen = generator::NativeGenerator::from_ruby(schema_spec, seed, locale)?;
100
+ gen.generate_one_to_ruby(ruby)
101
+ }
102
+
103
+ /// Get list of available type names
104
+ fn available_types() -> Vec<String> {
105
+ types::AVAILABLE_TYPES.iter().map(|s| s.to_string()).collect()
106
+ }
107
+
108
+ /// Get list of available locale codes
109
+ fn available_locales() -> Vec<String> {
110
+ vec![
111
+ "en".to_string(),
112
+ "fr_fr".to_string(),
113
+ "de_de".to_string(),
114
+ "zh_cn".to_string(),
115
+ "zh_tw".to_string(),
116
+ "ja_jp".to_string(),
117
+ "pt_br".to_string(),
118
+ "it_it".to_string(),
119
+ "nl_nl".to_string(),
120
+ "ar_sa".to_string(),
121
+ ]
122
+ }
123
+
124
+ /// Get native extension version
125
+ fn version() -> String {
126
+ env!("CARGO_PKG_VERSION").to_string()
127
+ }
128
+
129
+ /// Check if extension is loaded and functional
130
+ fn loaded() -> bool {
131
+ true
132
+ }
133
+
134
+ /// Get performance info
135
+ fn performance_info() -> String {
136
+ let cores = num_cpus();
137
+ let rayon_threads = rayon::current_num_threads();
138
+ format!(
139
+ "Native engine powered by fake-rs (Rust). Expected: 1-5M records/sec. \
140
+ Cores: {}, Threads: {} (default: {}, use 0 for all cores).",
141
+ cores,
142
+ rayon_threads,
143
+ DEFAULT_THREADS
144
+ )
145
+ }
146
+
147
+ fn num_cpus() -> usize {
148
+ std::thread::available_parallelism()
149
+ .map(|p| p.get())
150
+ .unwrap_or(1)
151
+ }
152
+
153
+ /// Get thread count info
154
+ fn thread_count() -> usize {
155
+ rayon::current_num_threads()
156
+ }
157
+
158
+ /// Set the number of threads to use for parallel generation
159
+ /// Pass 0 to use all available cores (default)
160
+ /// Returns the actual number of threads that will be used
161
+ ///
162
+ /// NOTE: This must be called before any generation operations.
163
+ /// Alternatively, set RAYON_NUM_THREADS environment variable before loading the gem.
164
+ ///
165
+ /// Example usage:
166
+ /// # Option 1: Environment variable (recommended)
167
+ /// # RAYON_NUM_THREADS=4 ruby my_script.rb
168
+ ///
169
+ /// # Option 2: Call set_threads early in your code
170
+ /// Synthra::Native.set_threads(4)
171
+ fn set_threads(num_threads: usize) -> Result<usize, Error> {
172
+ let threads = if num_threads == 0 {
173
+ num_cpus()
174
+ } else {
175
+ num_threads.min(num_cpus())
176
+ };
177
+
178
+ THREAD_LIMIT.store(threads, Ordering::SeqCst);
179
+
180
+ // Try to configure Rayon's global thread pool
181
+ // This only works if called before any parallel operations
182
+ match ThreadPoolBuilder::new()
183
+ .num_threads(threads)
184
+ .build_global()
185
+ {
186
+ Ok(_) => Ok(threads),
187
+ Err(_) => {
188
+ // Pool already initialized - return current thread count
189
+ Ok(rayon::current_num_threads())
190
+ }
191
+ }
192
+ }
193
+
194
+ /// Get the configured thread limit
195
+ fn get_thread_limit() -> usize {
196
+ let limit = THREAD_LIMIT.load(Ordering::SeqCst);
197
+ if limit == 0 {
198
+ rayon::current_num_threads()
199
+ } else {
200
+ limit
201
+ }
202
+ }
203
+
204
+ /// Initialize the native extension module
205
+ #[magnus::init]
206
+ fn init(ruby: &Ruby) -> Result<(), Error> {
207
+ let module = ruby.define_module("Synthra")?;
208
+ let native = module.define_module("Native")?;
209
+
210
+ // Core generation methods
211
+ native.define_singleton_method("generate", function!(generate, 5))?;
212
+ native.define_singleton_method("generate_to_file", function!(generate_to_file, 7))?;
213
+ native.define_singleton_method("generate_one", function!(generate_one, 3))?;
214
+
215
+ // Introspection methods
216
+ native.define_singleton_method("available_types", function!(available_types, 0))?;
217
+ native.define_singleton_method("available_locales", function!(available_locales, 0))?;
218
+ native.define_singleton_method("version", function!(version, 0))?;
219
+ native.define_singleton_method("loaded?", function!(loaded, 0))?;
220
+ native.define_singleton_method("performance_info", function!(performance_info, 0))?;
221
+ native.define_singleton_method("thread_count", function!(thread_count, 0))?;
222
+
223
+ // Thread control methods
224
+ native.define_singleton_method("set_threads", function!(set_threads, 1))?;
225
+ native.define_singleton_method("get_thread_limit", function!(get_thread_limit, 0))?;
226
+
227
+ Ok(())
228
+ }
229
+