sz_rust_sdk/traits.rs
1//! Core traits defining the Senzing SDK interface
2//!
3//! This module contains the main trait definitions that mirror the C# SDK interfaces.
4//! These traits define the contract for interacting with the Senzing engine.
5
6use crate::{error::SzResult, flags::SzFlags, types::*};
7use std::collections::HashSet;
8
9/// Main entry point and factory for Senzing SDK components.
10///
11/// The `SzEnvironment` trait provides the primary interface for initializing
12/// the Senzing SDK and obtaining instances of other SDK components. This is
13/// the first interface you interact with when using the SDK.
14///
15/// # Example
16///
17/// ```
18/// # use sz_rust_sdk::helpers::ExampleEnvironment;
19/// # let env = ExampleEnvironment::initialize("doctest_sz_environment")?;
20/// use sz_rust_sdk::prelude::*;
21///
22/// // Get component interfaces
23/// let engine = env.get_engine()?;
24/// let product = env.get_product()?;
25/// # Ok::<(), SzError>(())
26/// ```
27///
28/// # Singleton Pattern
29///
30/// `SzEnvironmentCore` implements a singleton pattern. Multiple calls to
31/// `get_instance` with the same parameters return the same instance.
32pub trait SzEnvironment: Send + Sync {
33 /// Checks if the environment has been destroyed.
34 ///
35 /// # Returns
36 ///
37 /// `true` if `destroy()` has been called, `false` otherwise.
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
43 /// use sz_rust_sdk::prelude::*;
44 ///
45 /// # let env = ExampleEnvironment::initialize("doctest_is_destroyed")?;
46 /// let destroyed = env.is_destroyed();
47 /// assert!(!destroyed);
48 /// # Ok::<(), SzError>(())
49 /// ```
50 fn is_destroyed(&self) -> bool;
51
52 /// Reinitializes the environment with a different configuration.
53 ///
54 /// Switches to a different registered configuration without destroying
55 /// the environment. This is thread-safe and can be called while other
56 /// operations are in progress.
57 ///
58 /// # Arguments
59 ///
60 /// * `config_id` - ID of a registered configuration to activate
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
66 /// use sz_rust_sdk::prelude::*;
67 ///
68 /// # let env = ExampleEnvironment::initialize("doctest_reinitialize")?;
69 /// let config_id = env.get_active_config_id()?;
70 /// env.reinitialize(config_id)?;
71 /// # Ok::<(), SzError>(())
72 /// ```
73 ///
74 /// # Errors
75 ///
76 /// * `SzError::NotFound` - Configuration ID does not exist
77 /// * `SzError::EnvironmentDestroyed` - Environment was destroyed
78 fn reinitialize(&self, config_id: ConfigId) -> SzResult<()>;
79
80 /// Gets the currently active configuration ID.
81 ///
82 /// # Returns
83 ///
84 /// The configuration ID currently in use by the engine.
85 ///
86 /// # Examples
87 ///
88 /// ```
89 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
90 /// use sz_rust_sdk::prelude::*;
91 ///
92 /// # let env = ExampleEnvironment::initialize("doctest_get_active_config_id")?;
93 /// let config_id = env.get_active_config_id()?;
94 /// println!("Active config ID: {}", config_id);
95 /// # Ok::<(), SzError>(())
96 /// ```
97 ///
98 /// # Errors
99 ///
100 /// * `SzError::EnvironmentDestroyed` - Environment was destroyed
101 fn get_active_config_id(&self) -> SzResult<ConfigId>;
102
103 /// Gets the product interface for version and license information.
104 ///
105 /// # Returns
106 ///
107 /// An [`SzProduct`] instance for querying product information.
108 ///
109 /// # Examples
110 ///
111 /// ```
112 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
113 /// use sz_rust_sdk::prelude::*;
114 ///
115 /// # let env = ExampleEnvironment::initialize("doctest_get_product")?;
116 /// let product = env.get_product()?;
117 /// let version = product.get_version()?;
118 /// println!("Senzing version: {}", version);
119 /// # Ok::<(), SzError>(())
120 /// ```
121 ///
122 /// # Errors
123 ///
124 /// * `SzError::EnvironmentDestroyed` - Environment was destroyed
125 fn get_product(&self) -> SzResult<Box<dyn SzProduct>>;
126
127 /// Gets the engine interface for entity resolution operations.
128 ///
129 /// # Returns
130 ///
131 /// An [`SzEngine`] instance for adding records, searching, and analysis.
132 ///
133 /// # Examples
134 ///
135 /// ```
136 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
137 /// use sz_rust_sdk::prelude::*;
138 ///
139 /// # let env = ExampleEnvironment::initialize("doctest_get_engine")?;
140 /// let engine = env.get_engine()?;
141 /// # Ok::<(), SzError>(())
142 /// ```
143 ///
144 /// # Errors
145 ///
146 /// * `SzError::EnvironmentDestroyed` - Environment was destroyed
147 fn get_engine(&self) -> SzResult<Box<dyn SzEngine>>;
148
149 /// Gets the configuration manager interface.
150 ///
151 /// # Returns
152 ///
153 /// An [`SzConfigManager`] instance for managing configuration versions.
154 ///
155 /// # Examples
156 ///
157 /// ```
158 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
159 /// use sz_rust_sdk::prelude::*;
160 ///
161 /// # let env = ExampleEnvironment::initialize("doctest_get_config_manager")?;
162 /// let config_mgr = env.get_config_manager()?;
163 /// # Ok::<(), SzError>(())
164 /// ```
165 ///
166 /// # Errors
167 ///
168 /// * `SzError::EnvironmentDestroyed` - Environment was destroyed
169 fn get_config_manager(&self) -> SzResult<Box<dyn SzConfigManager>>;
170
171 /// Gets the diagnostic interface for system monitoring.
172 ///
173 /// # Returns
174 ///
175 /// An [`SzDiagnostic`] instance for performance testing and repository info.
176 ///
177 /// # Examples
178 ///
179 /// ```
180 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
181 /// use sz_rust_sdk::prelude::*;
182 ///
183 /// # let env = ExampleEnvironment::initialize("doctest_get_diagnostic")?;
184 /// let diagnostic = env.get_diagnostic()?;
185 /// # Ok::<(), SzError>(())
186 /// ```
187 ///
188 /// # Errors
189 ///
190 /// * `SzError::EnvironmentDestroyed` - Environment was destroyed
191 fn get_diagnostic(&self) -> SzResult<Box<dyn SzDiagnostic>>;
192}
193
194/// Core entity resolution engine operations.
195///
196/// The `SzEngine` trait provides methods for adding records, retrieving entities,
197/// performing searches, and conducting various types of analysis. This is the
198/// primary interface for entity resolution operations.
199///
200/// # Obtaining an Instance
201///
202/// ```
203/// # use sz_rust_sdk::helpers::ExampleEnvironment;
204/// # let env = ExampleEnvironment::initialize("doctest_sz_engine")?;
205/// use sz_rust_sdk::prelude::*;
206///
207/// let engine = env.get_engine()?;
208/// # Ok::<(), SzError>(())
209/// ```
210pub trait SzEngine: Send + Sync {
211 /// Primes the engine for optimal performance.
212 ///
213 /// Loads internal caches and prepares the engine for high-throughput operations.
214 /// Call this once after initialization when processing large batches of records.
215 ///
216 /// # Examples
217 ///
218 /// ```
219 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
220 /// use sz_rust_sdk::prelude::*;
221 ///
222 /// # let env = ExampleEnvironment::initialize("doctest_prime_engine")?;
223 /// let engine = env.get_engine()?;
224 ///
225 /// engine.prime_engine()?;
226 /// # Ok::<(), SzError>(())
227 /// ```
228 ///
229 /// # Errors
230 ///
231 /// Returns `SzError::NotInitialized` if the environment is not initialized.
232 fn prime_engine(&self) -> SzResult<()>;
233
234 /// Gets engine performance statistics.
235 ///
236 /// Returns a JSON object containing internal performance metrics useful for
237 /// monitoring and debugging.
238 ///
239 /// # Returns
240 ///
241 /// JSON string with engine statistics including cache hit rates and timing data.
242 ///
243 /// # Examples
244 ///
245 /// ```
246 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
247 /// use sz_rust_sdk::prelude::*;
248 ///
249 /// # let env = ExampleEnvironment::initialize("doctest_get_stats")?;
250 /// let engine = env.get_engine()?;
251 ///
252 /// let stats = engine.get_stats()?;
253 /// assert!(!stats.is_empty());
254 /// # Ok::<(), SzError>(())
255 /// ```
256 fn get_stats(&self) -> SzResult<JsonString>;
257
258 /// Adds a record for entity resolution.
259 ///
260 /// Inserts or updates a record in the entity repository. The record will be
261 /// matched and potentially merged with existing entities based on configured rules.
262 ///
263 /// # Arguments
264 ///
265 /// * `data_source_code` - The data source identifier (must be registered)
266 /// * `record_id` - Unique identifier for the record within the data source
267 /// * `record_definition` - JSON object containing the record attributes
268 /// * `flags` - Optional flags controlling what information is returned
269 ///
270 /// # Returns
271 ///
272 /// JSON string with information about affected entities (when flags request it).
273 ///
274 /// # Examples
275 ///
276 /// ```
277 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
278 /// use sz_rust_sdk::prelude::*;
279 ///
280 /// # let env = ExampleEnvironment::initialize("doctest_add_record")?;
281 /// let engine = env.get_engine()?;
282 ///
283 /// let record = r#"{"NAME_FULL": "John Smith", "ADDR_FULL": "123 Main St"}"#;
284 /// let result = engine.add_record("TEST", "ADD_1001", record, None)?;
285 /// # Ok::<(), SzError>(())
286 /// ```
287 ///
288 /// With flags to get entity info back:
289 ///
290 /// ```
291 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
292 /// use sz_rust_sdk::prelude::*;
293 ///
294 /// # let env = ExampleEnvironment::initialize("doctest_add_record_flags")?;
295 /// let engine = env.get_engine()?;
296 ///
297 /// let record = r#"{"NAME_FULL": "Jane Doe", "EMAIL": "jane@example.com"}"#;
298 /// let result = engine.add_record(
299 /// "TEST",
300 /// "ADD_1002",
301 /// record,
302 /// Some(SzFlags::WITH_INFO),
303 /// )?;
304 /// // result contains affected entity info when WITH_INFO is set
305 /// # Ok::<(), SzError>(())
306 /// ```
307 ///
308 /// # Errors
309 ///
310 /// * `SzError::UnknownDataSource` - Data source is not registered
311 /// * `SzError::BadInput` - Invalid JSON or missing required fields
312 fn add_record(
313 &self,
314 data_source_code: &str,
315 record_id: &str,
316 record_definition: &str,
317 flags: Option<SzFlags>,
318 ) -> SzResult<JsonString>;
319
320 /// Gets a preview of how a record would be processed without persisting it.
321 ///
322 /// Useful for testing record mappings and seeing how features would be extracted
323 /// before committing the record to the repository.
324 ///
325 /// # Arguments
326 ///
327 /// * `record_definition` - JSON object containing the record attributes
328 /// * `flags` - Optional flags controlling what information is returned
329 ///
330 /// # Returns
331 ///
332 /// JSON string showing extracted features and potential matches.
333 ///
334 /// # Examples
335 ///
336 /// ```
337 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
338 /// use sz_rust_sdk::prelude::*;
339 ///
340 /// # let env = ExampleEnvironment::initialize("doctest_get_record_preview")?;
341 /// let engine = env.get_engine()?;
342 ///
343 /// let record = r#"{"NAME_FULL": "John Smith", "ADDR_FULL": "123 Main St"}"#;
344 /// let preview = engine.get_record_preview(record, None)?;
345 /// # Ok::<(), SzError>(())
346 /// ```
347 fn get_record_preview(
348 &self,
349 record_definition: &str,
350 flags: Option<SzFlags>,
351 ) -> SzResult<JsonString>;
352
353 /// Deletes a record from the entity repository.
354 ///
355 /// Removes the record and re-resolves any affected entities. If the record
356 /// was the only record in an entity, the entity is also removed.
357 ///
358 /// # Arguments
359 ///
360 /// * `data_source_code` - The data source identifier
361 /// * `record_id` - The record identifier to delete
362 /// * `flags` - Optional flags controlling what information is returned
363 ///
364 /// # Returns
365 ///
366 /// JSON string with information about affected entities.
367 ///
368 /// # Examples
369 ///
370 /// ```
371 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
372 /// use sz_rust_sdk::prelude::*;
373 ///
374 /// # let env = ExampleEnvironment::initialize("doctest_delete_record")?;
375 /// let engine = env.get_engine()?;
376 ///
377 /// // First add a record, then delete it
378 /// # engine.add_record("TEST", "DEL_1001",
379 /// # r#"{"NAME_FULL": "Delete Me"}"#, None)?;
380 /// let result = engine.delete_record("TEST", "DEL_1001", None)?;
381 /// # Ok::<(), SzError>(())
382 /// ```
383 ///
384 /// # Errors
385 ///
386 /// * `SzError::UnknownDataSource` - Data source is not registered
387 /// * `SzError::NotFound` - Record does not exist
388 fn delete_record(
389 &self,
390 data_source_code: &str,
391 record_id: &str,
392 flags: Option<SzFlags>,
393 ) -> SzResult<JsonString>;
394
395 /// Reevaluates a specific record against current rules.
396 ///
397 /// Forces re-resolution of a record using the current configuration. Useful
398 /// after configuration changes to update entity assignments.
399 ///
400 /// # Arguments
401 ///
402 /// * `data_source_code` - The data source identifier
403 /// * `record_id` - The record identifier to reevaluate
404 /// * `flags` - Optional flags controlling what information is returned
405 ///
406 /// # Returns
407 ///
408 /// JSON string with reevaluation results.
409 ///
410 /// # Examples
411 ///
412 /// ```
413 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
414 /// use sz_rust_sdk::prelude::*;
415 ///
416 /// # let env = ExampleEnvironment::initialize("doctest_reevaluate_record")?;
417 /// let engine = env.get_engine()?;
418 /// # engine.add_record("TEST", "REEV_REC_1001",
419 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
420 ///
421 /// let result = engine.reevaluate_record("TEST", "REEV_REC_1001", None)?;
422 /// # Ok::<(), SzError>(())
423 /// ```
424 ///
425 /// # Errors
426 ///
427 /// * `SzError::NotFound` - Record does not exist
428 fn reevaluate_record(
429 &self,
430 data_source_code: &str,
431 record_id: &str,
432 flags: Option<SzFlags>,
433 ) -> SzResult<JsonString>;
434
435 /// Reevaluates all records for a specific entity.
436 ///
437 /// Forces re-resolution of all records in an entity. The entity may split
438 /// into multiple entities or merge with others based on current rules.
439 ///
440 /// # Arguments
441 ///
442 /// * `entity_id` - The entity identifier to reevaluate
443 /// * `flags` - Optional flags controlling what information is returned
444 ///
445 /// # Returns
446 ///
447 /// JSON string with reevaluation results.
448 ///
449 /// # Examples
450 ///
451 /// ```
452 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
453 /// use sz_rust_sdk::prelude::*;
454 ///
455 /// # let env = ExampleEnvironment::initialize("doctest_reevaluate_entity")?;
456 /// let engine = env.get_engine()?;
457 /// # engine.add_record("TEST", "REEV_ENT_1001",
458 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
459 /// # let result = engine.get_entity(
460 /// # EntityRef::Record { data_source: "TEST", record_id: "REEV_ENT_1001" },
461 /// # None,
462 /// # )?;
463 /// # let entity_json: serde_json::Value = serde_json::from_str(&result).unwrap();
464 /// # let entity_id = entity_json["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
465 ///
466 /// let result = engine.reevaluate_entity(entity_id, None)?;
467 /// # Ok::<(), SzError>(())
468 /// ```
469 ///
470 /// # Errors
471 ///
472 /// * `SzError::NotFound` - Entity does not exist
473 fn reevaluate_entity(
474 &self,
475 entity_id: EntityId,
476 flags: Option<SzFlags>,
477 ) -> SzResult<JsonString>;
478
479 /// Searches for entities by attributes.
480 ///
481 /// Finds entities that match the provided attributes. Returns scored results
482 /// based on match quality.
483 ///
484 /// # Arguments
485 ///
486 /// * `attributes` - JSON object with search attributes (e.g., name, address)
487 /// * `search_profile` - Optional search profile name for customized matching
488 /// * `flags` - Optional flags controlling result detail level
489 ///
490 /// # Returns
491 ///
492 /// JSON string with matching entities and match scores.
493 ///
494 /// # Examples
495 ///
496 /// ```
497 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
498 /// use sz_rust_sdk::prelude::*;
499 ///
500 /// # let env = ExampleEnvironment::initialize("doctest_search")?;
501 /// let engine = env.get_engine()?;
502 ///
503 /// let attrs = r#"{"NAME_FULL": "John Smith"}"#;
504 /// let results = engine.search_by_attributes(attrs, None, None)?;
505 /// # Ok::<(), SzError>(())
506 /// ```
507 ///
508 /// # Errors
509 ///
510 /// * `SzError::BadInput` - Invalid JSON attributes
511 fn search_by_attributes(
512 &self,
513 attributes: &str,
514 search_profile: Option<&str>,
515 flags: Option<SzFlags>,
516 ) -> SzResult<JsonString>;
517
518 /// Analyzes why a search result was returned for an entity.
519 ///
520 /// Provides detailed explanation of why a particular entity matched the
521 /// search criteria, including feature comparisons and match scores.
522 ///
523 /// # Arguments
524 ///
525 /// * `attributes` - JSON object with search attributes
526 /// * `entity_id` - The entity to analyze
527 /// * `search_profile` - Optional search profile name
528 /// * `flags` - Optional flags controlling detail level
529 ///
530 /// # Returns
531 ///
532 /// JSON string with detailed match analysis.
533 ///
534 /// # Examples
535 ///
536 /// ```
537 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
538 /// use sz_rust_sdk::prelude::*;
539 ///
540 /// # let env = ExampleEnvironment::initialize("doctest_why_search")?;
541 /// let engine = env.get_engine()?;
542 /// # engine.add_record("TEST", "WHYS_1001",
543 /// # r#"{"NAME_FULL": "John Smith", "ADDR_FULL": "123 Main St"}"#, None)?;
544 /// # let result = engine.get_entity(
545 /// # EntityRef::Record { data_source: "TEST", record_id: "WHYS_1001" },
546 /// # None,
547 /// # )?;
548 /// # let entity_json: serde_json::Value = serde_json::from_str(&result).unwrap();
549 /// # let entity_id = entity_json["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
550 ///
551 /// let attrs = r#"{"NAME_FULL": "John Smith"}"#;
552 /// let result = engine.why_search(attrs, entity_id, None, None)?;
553 /// # Ok::<(), SzError>(())
554 /// ```
555 fn why_search(
556 &self,
557 attributes: &str,
558 entity_id: EntityId,
559 search_profile: Option<&str>,
560 flags: Option<SzFlags>,
561 ) -> SzResult<JsonString>;
562
563 /// Gets entity information by entity ID or record key.
564 ///
565 /// Retrieves complete entity data including all constituent records and
566 /// relationships. The entity can be specified either by its entity ID
567 /// or by a record key (data source + record ID).
568 ///
569 /// # Arguments
570 ///
571 /// * `entity_ref` - Reference to the entity (entity ID or record key)
572 /// * `flags` - Optional flags controlling what data is included
573 ///
574 /// # Returns
575 ///
576 /// JSON string with entity details.
577 ///
578 /// # Errors
579 ///
580 /// * `SzError::NotFound` - Entity or record does not exist
581 ///
582 /// # Examples
583 ///
584 /// By record key:
585 ///
586 /// ```
587 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
588 /// use sz_rust_sdk::prelude::*;
589 ///
590 /// # let env = ExampleEnvironment::initialize("doctest_get_entity")?;
591 /// let engine = env.get_engine()?;
592 /// # engine.add_record("TEST", "ENT_1001",
593 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
594 ///
595 /// let entity = engine.get_entity(
596 /// EntityRef::Record { data_source: "TEST", record_id: "ENT_1001" },
597 /// None,
598 /// )?;
599 /// # Ok::<(), SzError>(())
600 /// ```
601 fn get_entity(&self, entity_ref: EntityRef, flags: Option<SzFlags>) -> SzResult<JsonString>;
602
603 /// Gets record information.
604 ///
605 /// Retrieves the original record data as stored in the repository.
606 ///
607 /// # Arguments
608 ///
609 /// * `data_source_code` - The data source identifier
610 /// * `record_id` - The record identifier
611 /// * `flags` - Optional flags controlling what data is included
612 ///
613 /// # Returns
614 ///
615 /// JSON string with record details.
616 ///
617 /// # Examples
618 ///
619 /// ```
620 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
621 /// use sz_rust_sdk::prelude::*;
622 ///
623 /// # let env = ExampleEnvironment::initialize("doctest_get_record")?;
624 /// let engine = env.get_engine()?;
625 /// # engine.add_record("TEST", "REC_1001",
626 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
627 ///
628 /// let record = engine.get_record("TEST", "REC_1001", None)?;
629 /// # Ok::<(), SzError>(())
630 /// ```
631 ///
632 /// # Errors
633 ///
634 /// * `SzError::NotFound` - Record does not exist
635 fn get_record(
636 &self,
637 data_source_code: &str,
638 record_id: &str,
639 flags: Option<SzFlags>,
640 ) -> SzResult<JsonString>;
641
642 /// Finds interesting entities related to a given entity or record.
643 ///
644 /// Identifies entities with notable relationships to the specified entity,
645 /// such as disclosed relationships or possible matches. The entity can be
646 /// specified either by its entity ID or by a record key.
647 ///
648 /// # Arguments
649 ///
650 /// * `entity_ref` - Reference to the entity (entity ID or record key)
651 /// * `flags` - Optional flags controlling result detail
652 ///
653 /// # Returns
654 ///
655 /// JSON string with interesting entity relationships.
656 ///
657 /// # Examples
658 ///
659 /// ```
660 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
661 /// use sz_rust_sdk::prelude::*;
662 ///
663 /// # let env = ExampleEnvironment::initialize("doctest_find_interesting")?;
664 /// let engine = env.get_engine()?;
665 /// # engine.add_record("TEST", "INT_1001",
666 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
667 ///
668 /// let entity = engine.get_entity(
669 /// EntityRef::Record { data_source: "TEST", record_id: "INT_1001" },
670 /// None,
671 /// )?;
672 /// // Parse entity_id from the result, then find interesting entities
673 /// # Ok::<(), SzError>(())
674 /// ```
675 fn find_interesting_entities(
676 &self,
677 entity_ref: EntityRef,
678 flags: Option<SzFlags>,
679 ) -> SzResult<JsonString>;
680
681 /// Finds a relationship path between two entities.
682 ///
683 /// Discovers the shortest path connecting two entities through their
684 /// relationships, useful for understanding indirect connections.
685 ///
686 /// # Arguments
687 ///
688 /// * `start_entity_id` - Starting entity
689 /// * `end_entity_id` - Target entity
690 /// * `max_degrees` - Maximum relationship hops to traverse
691 /// * `avoid_entity_ids` - Optional entities to exclude from the path
692 /// * `required_data_sources` - Optional data sources that must appear in path
693 /// * `flags` - Optional flags controlling result detail
694 ///
695 /// # Returns
696 ///
697 /// JSON string with path details and intermediate entities.
698 ///
699 /// # Examples
700 ///
701 /// ```
702 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
703 /// use sz_rust_sdk::prelude::*;
704 ///
705 /// # let env = ExampleEnvironment::initialize("doctest_find_path")?;
706 /// let engine = env.get_engine()?;
707 /// # engine.add_record("TEST", "PATH_1001",
708 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
709 /// # engine.add_record("TEST", "PATH_1002",
710 /// # r#"{"NAME_FULL": "Jane Doe"}"#, None)?;
711 /// # let r1 = engine.get_entity(
712 /// # EntityRef::Record { data_source: "TEST", record_id: "PATH_1001" },
713 /// # None,
714 /// # )?;
715 /// # let j1: serde_json::Value = serde_json::from_str(&r1).unwrap();
716 /// # let entity_id1 = j1["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
717 /// # let r2 = engine.get_entity(
718 /// # EntityRef::Record { data_source: "TEST", record_id: "PATH_1002" },
719 /// # None,
720 /// # )?;
721 /// # let j2: serde_json::Value = serde_json::from_str(&r2).unwrap();
722 /// # let entity_id2 = j2["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
723 ///
724 /// let path = engine.find_path(entity_id1, entity_id2, 3, None, None, None)?;
725 /// # Ok::<(), SzError>(())
726 /// ```
727 fn find_path(
728 &self,
729 start_entity_id: EntityId,
730 end_entity_id: EntityId,
731 max_degrees: i64,
732 avoid_entity_ids: Option<&HashSet<EntityId>>,
733 required_data_sources: Option<&HashSet<String>>,
734 flags: Option<SzFlags>,
735 ) -> SzResult<JsonString>;
736
737 /// Finds a network of related entities.
738 ///
739 /// Builds a network graph starting from one or more seed entities,
740 /// expanding outward through relationships.
741 ///
742 /// # Arguments
743 ///
744 /// * `entity_list` - Seed entity IDs to start from
745 /// * `max_degrees` - Maximum relationship hops from seed entities
746 /// * `build_out_degree` - Degrees to expand for building connections
747 /// * `max_entities` - Maximum entities to include in the network
748 /// * `flags` - Optional flags controlling result detail
749 ///
750 /// # Returns
751 ///
752 /// JSON string with network graph data.
753 ///
754 /// # Examples
755 ///
756 /// ```
757 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
758 /// use sz_rust_sdk::prelude::*;
759 ///
760 /// # let env = ExampleEnvironment::initialize("doctest_find_network")?;
761 /// let engine = env.get_engine()?;
762 /// # engine.add_record("TEST", "NET_1001",
763 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
764 /// # let r1 = engine.get_entity(
765 /// # EntityRef::Record { data_source: "TEST", record_id: "NET_1001" },
766 /// # None,
767 /// # )?;
768 /// # let j1: serde_json::Value = serde_json::from_str(&r1).unwrap();
769 /// # let entity_id = j1["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
770 ///
771 /// let network = engine.find_network(&[entity_id], 3, 1, 100, None)?;
772 /// # Ok::<(), SzError>(())
773 /// ```
774 fn find_network(
775 &self,
776 entity_list: &[EntityId],
777 max_degrees: i64,
778 build_out_degree: i64,
779 max_entities: i64,
780 flags: Option<SzFlags>,
781 ) -> SzResult<JsonString>;
782
783 /// Analyzes why two entities are related.
784 ///
785 /// Provides detailed explanation of the relationship between two entities,
786 /// including shared features and match scores.
787 ///
788 /// # Arguments
789 ///
790 /// * `entity_id1` - First entity
791 /// * `entity_id2` - Second entity
792 /// * `flags` - Optional flags controlling detail level
793 ///
794 /// # Returns
795 ///
796 /// JSON string with relationship analysis.
797 ///
798 /// # Examples
799 ///
800 /// ```
801 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
802 /// use sz_rust_sdk::prelude::*;
803 ///
804 /// # let env = ExampleEnvironment::initialize("doctest_why_entities")?;
805 /// let engine = env.get_engine()?;
806 /// # engine.add_record("TEST", "WHYE_1001",
807 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
808 /// # engine.add_record("TEST", "WHYE_1002",
809 /// # r#"{"NAME_FULL": "Jane Doe"}"#, None)?;
810 /// # let r1 = engine.get_entity(
811 /// # EntityRef::Record { data_source: "TEST", record_id: "WHYE_1001" },
812 /// # None,
813 /// # )?;
814 /// # let j1: serde_json::Value = serde_json::from_str(&r1).unwrap();
815 /// # let entity_id1 = j1["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
816 /// # let r2 = engine.get_entity(
817 /// # EntityRef::Record { data_source: "TEST", record_id: "WHYE_1002" },
818 /// # None,
819 /// # )?;
820 /// # let j2: serde_json::Value = serde_json::from_str(&r2).unwrap();
821 /// # let entity_id2 = j2["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
822 ///
823 /// let result = engine.why_entities(entity_id1, entity_id2, None)?;
824 /// # Ok::<(), SzError>(())
825 /// ```
826 fn why_entities(
827 &self,
828 entity_id1: EntityId,
829 entity_id2: EntityId,
830 flags: Option<SzFlags>,
831 ) -> SzResult<JsonString>;
832
833 /// Analyzes why two records resolved together.
834 ///
835 /// Explains why two specific records were merged into the same entity,
836 /// showing the matching features and rules that caused the merge.
837 ///
838 /// # Arguments
839 ///
840 /// * `data_source_code1` - First record's data source
841 /// * `record_id1` - First record's identifier
842 /// * `data_source_code2` - Second record's data source
843 /// * `record_id2` - Second record's identifier
844 /// * `flags` - Optional flags controlling detail level
845 ///
846 /// # Returns
847 ///
848 /// JSON string with merge analysis.
849 ///
850 /// # Examples
851 ///
852 /// ```
853 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
854 /// use sz_rust_sdk::prelude::*;
855 ///
856 /// # let env = ExampleEnvironment::initialize("doctest_why_records")?;
857 /// let engine = env.get_engine()?;
858 /// # engine.add_record("TEST", "WHYR_1001",
859 /// # r#"{"NAME_FULL": "John Smith", "ADDR_FULL": "123 Main St"}"#, None)?;
860 /// # engine.add_record("TEST", "WHYR_1002",
861 /// # r#"{"NAME_FULL": "John Smith", "EMAIL": "john@example.com"}"#, None)?;
862 ///
863 /// let result = engine.why_records("TEST", "WHYR_1001", "TEST", "WHYR_1002", None)?;
864 /// # Ok::<(), SzError>(())
865 /// ```
866 fn why_records(
867 &self,
868 data_source_code1: &str,
869 record_id1: &str,
870 data_source_code2: &str,
871 record_id2: &str,
872 flags: Option<SzFlags>,
873 ) -> SzResult<JsonString>;
874
875 /// Analyzes why a record belongs to its entity.
876 ///
877 /// Explains the chain of matches that connected a record to its current
878 /// entity assignment.
879 ///
880 /// # Arguments
881 ///
882 /// * `data_source_code` - The record's data source
883 /// * `record_id` - The record identifier
884 /// * `flags` - Optional flags controlling detail level
885 ///
886 /// # Returns
887 ///
888 /// JSON string with entity membership analysis.
889 ///
890 /// # Examples
891 ///
892 /// ```
893 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
894 /// use sz_rust_sdk::prelude::*;
895 ///
896 /// # let env = ExampleEnvironment::initialize("doctest_why_record_in_entity")?;
897 /// let engine = env.get_engine()?;
898 /// # engine.add_record("TEST", "WRIE_1001",
899 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
900 ///
901 /// let result = engine.why_record_in_entity("TEST", "WRIE_1001", None)?;
902 /// # Ok::<(), SzError>(())
903 /// ```
904 fn why_record_in_entity(
905 &self,
906 data_source_code: &str,
907 record_id: &str,
908 flags: Option<SzFlags>,
909 ) -> SzResult<JsonString>;
910
911 /// Analyzes how an entity was constructed.
912 ///
913 /// Provides a step-by-step explanation of how records were merged to form
914 /// the current entity, useful for understanding complex resolution paths.
915 ///
916 /// # Arguments
917 ///
918 /// * `entity_id` - The entity to analyze
919 /// * `flags` - Optional flags controlling detail level
920 ///
921 /// # Returns
922 ///
923 /// JSON string with entity construction history.
924 ///
925 /// # Examples
926 ///
927 /// ```
928 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
929 /// use sz_rust_sdk::prelude::*;
930 ///
931 /// # let env = ExampleEnvironment::initialize("doctest_how_entity")?;
932 /// let engine = env.get_engine()?;
933 /// # engine.add_record("TEST", "HOW_1001",
934 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
935 /// # let result = engine.get_entity(
936 /// # EntityRef::Record { data_source: "TEST", record_id: "HOW_1001" },
937 /// # None,
938 /// # )?;
939 /// # let entity_json: serde_json::Value = serde_json::from_str(&result).unwrap();
940 /// # let entity_id = entity_json["RESOLVED_ENTITY"]["ENTITY_ID"].as_i64().unwrap();
941 ///
942 /// let result = engine.how_entity(entity_id, None)?;
943 /// # Ok::<(), SzError>(())
944 /// ```
945 fn how_entity(&self, entity_id: EntityId, flags: Option<SzFlags>) -> SzResult<JsonString>;
946
947 /// Creates a virtual entity from record keys without persisting.
948 ///
949 /// Simulates what an entity would look like if the specified records were
950 /// merged, without affecting the actual repository.
951 ///
952 /// # Arguments
953 ///
954 /// * `record_keys` - Pairs of (data_source_code, record_id)
955 /// * `flags` - Optional flags controlling result detail
956 ///
957 /// # Returns
958 ///
959 /// JSON string with virtual entity data.
960 ///
961 /// # Examples
962 ///
963 /// ```
964 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
965 /// use sz_rust_sdk::prelude::*;
966 ///
967 /// # let env = ExampleEnvironment::initialize("doctest_get_virtual_entity")?;
968 /// let engine = env.get_engine()?;
969 /// # engine.add_record("TEST", "VIRT_1001",
970 /// # r#"{"NAME_FULL": "John Smith"}"#, None)?;
971 /// # engine.add_record("TEST", "VIRT_1002",
972 /// # r#"{"NAME_FULL": "Jane Doe"}"#, None)?;
973 ///
974 /// let record_keys = vec![
975 /// ("TEST".to_string(), "VIRT_1001".to_string()),
976 /// ("TEST".to_string(), "VIRT_1002".to_string()),
977 /// ];
978 /// let result = engine.get_virtual_entity(&record_keys, None)?;
979 /// # Ok::<(), SzError>(())
980 /// ```
981 fn get_virtual_entity(
982 &self,
983 record_keys: &[(String, String)],
984 flags: Option<SzFlags>,
985 ) -> SzResult<JsonString>;
986
987 /// Processes a redo record for deferred resolution.
988 ///
989 /// Handles records that were queued for later processing due to conflicts
990 /// or resource constraints.
991 ///
992 /// # Arguments
993 ///
994 /// * `redo_record` - The redo record JSON from `get_redo_record`
995 /// * `flags` - Optional flags controlling result detail
996 ///
997 /// # Returns
998 ///
999 /// JSON string with processing results.
1000 ///
1001 /// # Examples
1002 ///
1003 /// ```
1004 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1005 /// use sz_rust_sdk::prelude::*;
1006 ///
1007 /// # let env = ExampleEnvironment::initialize("doctest_process_redo_record")?;
1008 /// let engine = env.get_engine()?;
1009 ///
1010 /// let redo = engine.get_redo_record()?;
1011 /// if !redo.is_empty() {
1012 /// let result = engine.process_redo_record(&redo, None)?;
1013 /// }
1014 /// # Ok::<(), SzError>(())
1015 /// ```
1016 fn process_redo_record(
1017 &self,
1018 redo_record: &str,
1019 flags: Option<SzFlags>,
1020 ) -> SzResult<JsonString>;
1021
1022 /// Gets the next pending redo record.
1023 ///
1024 /// Retrieves one record from the redo queue for processing.
1025 ///
1026 /// # Returns
1027 ///
1028 /// JSON string with redo record data, or empty string if queue is empty.
1029 ///
1030 /// # Examples
1031 ///
1032 /// ```
1033 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1034 /// use sz_rust_sdk::prelude::*;
1035 ///
1036 /// # let env = ExampleEnvironment::initialize("doctest_get_redo_record")?;
1037 /// let engine = env.get_engine()?;
1038 ///
1039 /// let redo = engine.get_redo_record()?;
1040 /// if redo.is_empty() {
1041 /// println!("No redo records pending");
1042 /// }
1043 /// # Ok::<(), SzError>(())
1044 /// ```
1045 fn get_redo_record(&self) -> SzResult<JsonString>;
1046
1047 /// Counts pending redo records.
1048 ///
1049 /// # Returns
1050 ///
1051 /// Number of records waiting in the redo queue.
1052 ///
1053 /// # Examples
1054 ///
1055 /// ```
1056 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1057 /// use sz_rust_sdk::prelude::*;
1058 ///
1059 /// # let env = ExampleEnvironment::initialize("doctest_count_redo_records")?;
1060 /// let engine = env.get_engine()?;
1061 ///
1062 /// let count = engine.count_redo_records()?;
1063 /// println!("Pending redo records: {}", count);
1064 /// # Ok::<(), SzError>(())
1065 /// ```
1066 fn count_redo_records(&self) -> SzResult<i64>;
1067
1068 /// Starts a JSON entity export.
1069 ///
1070 /// Initiates an export operation returning a handle for fetching results.
1071 /// Use `fetch_next` to retrieve data and `close_export` when done.
1072 ///
1073 /// # Arguments
1074 ///
1075 /// * `flags` - Optional flags controlling what data is exported
1076 ///
1077 /// # Returns
1078 ///
1079 /// Handle for fetching export data.
1080 ///
1081 /// # Examples
1082 ///
1083 /// Export all entities as JSON (full export loop):
1084 ///
1085 /// ```
1086 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1087 /// use sz_rust_sdk::prelude::*;
1088 ///
1089 /// # let env = ExampleEnvironment::initialize("doctest_export")?;
1090 /// let engine = env.get_engine()?;
1091 ///
1092 /// let handle = engine.export_json_entity_report(None)?;
1093 /// loop {
1094 /// let chunk = engine.fetch_next(handle)?;
1095 /// if chunk.is_empty() {
1096 /// break;
1097 /// }
1098 /// print!("{}", chunk);
1099 /// }
1100 /// engine.close_export(handle)?;
1101 /// # Ok::<(), SzError>(())
1102 /// ```
1103 fn export_json_entity_report(&self, flags: Option<SzFlags>) -> SzResult<ExportHandle>;
1104
1105 /// Starts a CSV entity export.
1106 ///
1107 /// Initiates a CSV export with specified columns.
1108 ///
1109 /// # Arguments
1110 ///
1111 /// * `csv_column_list` - Comma-separated list of columns to include
1112 /// * `flags` - Optional flags controlling what data is exported
1113 ///
1114 /// # Returns
1115 ///
1116 /// Handle for fetching export data.
1117 ///
1118 /// # Examples
1119 ///
1120 /// ```
1121 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1122 /// use sz_rust_sdk::prelude::*;
1123 ///
1124 /// # let env = ExampleEnvironment::initialize("doctest_export_csv")?;
1125 /// let engine = env.get_engine()?;
1126 ///
1127 /// let handle = engine.export_csv_entity_report(
1128 /// "RESOLVED_ENTITY_ID,RELATED_ENTITY_ID,MATCH_LEVEL_CODE",
1129 /// None,
1130 /// )?;
1131 /// loop {
1132 /// let chunk = engine.fetch_next(handle)?;
1133 /// if chunk.is_empty() {
1134 /// break;
1135 /// }
1136 /// print!("{}", chunk);
1137 /// }
1138 /// engine.close_export(handle)?;
1139 /// # Ok::<(), SzError>(())
1140 /// ```
1141 fn export_csv_entity_report(
1142 &self,
1143 csv_column_list: &str,
1144 flags: Option<SzFlags>,
1145 ) -> SzResult<ExportHandle>;
1146
1147 /// Fetches the next batch of export data.
1148 ///
1149 /// Call repeatedly until empty string is returned to get all export data.
1150 ///
1151 /// # Arguments
1152 ///
1153 /// * `export_handle` - Handle from `export_json_entity_report` or `export_csv_entity_report`
1154 ///
1155 /// # Returns
1156 ///
1157 /// Next batch of export data, or empty string when complete.
1158 ///
1159 /// # Examples
1160 ///
1161 /// ```
1162 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1163 /// use sz_rust_sdk::prelude::*;
1164 ///
1165 /// # let env = ExampleEnvironment::initialize("doctest_fetch_next")?;
1166 /// let engine = env.get_engine()?;
1167 ///
1168 /// let handle = engine.export_json_entity_report(None)?;
1169 /// let chunk = engine.fetch_next(handle)?;
1170 /// // Empty string means no more data
1171 /// engine.close_export(handle)?;
1172 /// # Ok::<(), SzError>(())
1173 /// ```
1174 fn fetch_next(&self, export_handle: ExportHandle) -> SzResult<JsonString>;
1175
1176 /// Closes an export operation and releases resources.
1177 ///
1178 /// Must be called when finished with an export to free the handle.
1179 ///
1180 /// # Arguments
1181 ///
1182 /// * `export_handle` - Handle to close
1183 ///
1184 /// # Examples
1185 ///
1186 /// ```
1187 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1188 /// use sz_rust_sdk::prelude::*;
1189 ///
1190 /// # let env = ExampleEnvironment::initialize("doctest_close_export")?;
1191 /// let engine = env.get_engine()?;
1192 ///
1193 /// let handle = engine.export_json_entity_report(None)?;
1194 /// // ... fetch data ...
1195 /// engine.close_export(handle)?;
1196 /// # Ok::<(), SzError>(())
1197 /// ```
1198 fn close_export(&self, export_handle: ExportHandle) -> SzResult<()>;
1199}
1200
1201/// Configuration management operations.
1202///
1203/// The `SzConfig` trait provides methods for managing Senzing configuration data,
1204/// including data source registration and configuration export.
1205///
1206/// # Obtaining an Instance
1207///
1208/// Configuration instances are obtained through [`SzConfigManager`]:
1209///
1210/// ```
1211/// # use sz_rust_sdk::helpers::ExampleEnvironment;
1212/// # let env = ExampleEnvironment::initialize("doctest_sz_config")?;
1213/// use sz_rust_sdk::prelude::*;
1214///
1215/// let config_mgr = env.get_config_manager()?;
1216/// let config = config_mgr.create_config()?;
1217/// # Ok::<(), SzError>(())
1218/// ```
1219pub trait SzConfig {
1220 /// Exports the complete configuration as JSON.
1221 ///
1222 /// Returns the full configuration definition that can be saved, modified,
1223 /// or registered as a new configuration version.
1224 ///
1225 /// # Returns
1226 ///
1227 /// JSON string containing the complete configuration.
1228 ///
1229 /// # Examples
1230 ///
1231 /// ```
1232 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1233 /// use sz_rust_sdk::prelude::*;
1234 ///
1235 /// # let env = ExampleEnvironment::initialize("doctest_config_export")?;
1236 /// let config_mgr = env.get_config_manager()?;
1237 /// let config = config_mgr.create_config()?;
1238 /// let json = config.export()?;
1239 /// assert!(!json.is_empty());
1240 /// # Ok::<(), SzError>(())
1241 /// ```
1242 fn export(&self) -> SzResult<JsonString>;
1243
1244 /// Gets the data source registry.
1245 ///
1246 /// Returns information about all registered data sources in this configuration.
1247 ///
1248 /// # Returns
1249 ///
1250 /// JSON string with array of data source definitions including codes and IDs.
1251 ///
1252 /// # Examples
1253 ///
1254 /// ```
1255 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1256 /// use sz_rust_sdk::prelude::*;
1257 ///
1258 /// # let env = ExampleEnvironment::initialize("doctest_get_data_source_registry")?;
1259 /// let config_mgr = env.get_config_manager()?;
1260 /// let config = config_mgr.create_config()?;
1261 /// let registry = config.get_data_source_registry()?;
1262 /// println!("Data sources: {}", registry);
1263 /// # Ok::<(), SzError>(())
1264 /// ```
1265 fn get_data_source_registry(&self) -> SzResult<JsonString>;
1266
1267 /// Registers a new data source.
1268 ///
1269 /// Adds a data source to the configuration. Data sources must be registered
1270 /// before records can be added from that source.
1271 ///
1272 /// # Arguments
1273 ///
1274 /// * `data_source_code` - Unique identifier for the data source (e.g., "CUSTOMERS", "WATCHLIST")
1275 ///
1276 /// # Returns
1277 ///
1278 /// JSON string with the registered data source details including assigned ID.
1279 ///
1280 /// # Examples
1281 ///
1282 /// ```
1283 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1284 /// use sz_rust_sdk::prelude::*;
1285 ///
1286 /// # let env = ExampleEnvironment::initialize("doctest_register_data_source")?;
1287 /// let config_mgr = env.get_config_manager()?;
1288 /// let config = config_mgr.create_config()?;
1289 /// let result = config.register_data_source("VENDORS")?;
1290 /// println!("Registered: {}", result);
1291 /// // Clean up by unregistering
1292 /// config.unregister_data_source("VENDORS")?;
1293 /// # Ok::<(), SzError>(())
1294 /// ```
1295 ///
1296 /// # Errors
1297 ///
1298 /// * `SzError::BadInput` - Data source code is invalid or already exists
1299 fn register_data_source(&self, data_source_code: &str) -> SzResult<JsonString>;
1300
1301 /// Removes a data source from the configuration.
1302 ///
1303 /// Unregisters a data source. This should only be done if no records exist
1304 /// from that data source.
1305 ///
1306 /// # Arguments
1307 ///
1308 /// * `data_source_code` - The data source identifier to remove
1309 ///
1310 /// # Examples
1311 ///
1312 /// ```
1313 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1314 /// use sz_rust_sdk::prelude::*;
1315 ///
1316 /// # let env = ExampleEnvironment::initialize("doctest_unregister_data_source")?;
1317 /// let config_mgr = env.get_config_manager()?;
1318 /// let config = config_mgr.create_config()?;
1319 /// # config.register_data_source("TEMP_SOURCE")?;
1320 /// config.unregister_data_source("TEMP_SOURCE")?;
1321 /// # Ok::<(), SzError>(())
1322 /// ```
1323 ///
1324 /// # Errors
1325 ///
1326 /// * `SzError::BadInput` - Data source does not exist
1327 fn unregister_data_source(&self, data_source_code: &str) -> SzResult<()>;
1328}
1329
1330/// Configuration lifecycle management.
1331///
1332/// The `SzConfigManager` trait provides methods for managing configuration
1333/// versions, registration, and deployment. Use this to create, modify, and
1334/// activate configuration versions.
1335///
1336/// # Obtaining an Instance
1337///
1338/// ```
1339/// # use sz_rust_sdk::helpers::ExampleEnvironment;
1340/// # let env = ExampleEnvironment::initialize("doctest_sz_config_manager")?;
1341/// use sz_rust_sdk::prelude::*;
1342///
1343/// let config_mgr = env.get_config_manager()?;
1344/// # Ok::<(), SzError>(())
1345/// ```
1346pub trait SzConfigManager {
1347 /// Creates a new configuration instance from the default template.
1348 ///
1349 /// Returns a configuration object that can be modified (e.g., adding data sources)
1350 /// before being registered and activated.
1351 ///
1352 /// # Returns
1353 ///
1354 /// A new [`SzConfig`] instance based on the default configuration template.
1355 ///
1356 /// # Examples
1357 ///
1358 /// ```
1359 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1360 /// use sz_rust_sdk::prelude::*;
1361 ///
1362 /// # let env = ExampleEnvironment::initialize("doctest_create_config")?;
1363 /// let config_mgr = env.get_config_manager()?;
1364 /// let config = config_mgr.create_config()?;
1365 /// let json = config.export()?;
1366 /// assert!(!json.is_empty());
1367 /// # Ok::<(), SzError>(())
1368 /// ```
1369 fn create_config(&self) -> SzResult<Box<dyn SzConfig>>;
1370
1371 /// Creates a configuration from an existing registered configuration.
1372 ///
1373 /// Loads a previously registered configuration for viewing or modification.
1374 ///
1375 /// # Arguments
1376 ///
1377 /// * `config_id` - ID of a registered configuration
1378 ///
1379 /// # Returns
1380 ///
1381 /// An [`SzConfig`] instance with the specified configuration loaded.
1382 ///
1383 /// # Examples
1384 ///
1385 /// ```
1386 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1387 /// use sz_rust_sdk::prelude::*;
1388 ///
1389 /// # let env = ExampleEnvironment::initialize("doctest_create_config_from_id")?;
1390 /// let config_mgr = env.get_config_manager()?;
1391 /// let config_id = config_mgr.get_default_config_id()?;
1392 /// let config = config_mgr.create_config_from_id(config_id)?;
1393 /// let json = config.export()?;
1394 /// assert!(!json.is_empty());
1395 /// # Ok::<(), SzError>(())
1396 /// ```
1397 ///
1398 /// # Errors
1399 ///
1400 /// * `SzError::NotFound` - Configuration ID does not exist
1401 fn create_config_from_id(&self, config_id: ConfigId) -> SzResult<Box<dyn SzConfig>>;
1402
1403 /// Creates a configuration from a JSON definition string.
1404 ///
1405 /// Parses a configuration JSON (e.g., from a file or `SzConfig::export()`)
1406 /// into a configuration object.
1407 ///
1408 /// # Arguments
1409 ///
1410 /// * `config_definition` - JSON string containing the configuration
1411 ///
1412 /// # Returns
1413 ///
1414 /// An [`SzConfig`] instance with the parsed configuration.
1415 ///
1416 /// # Examples
1417 ///
1418 /// ```
1419 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1420 /// use sz_rust_sdk::prelude::*;
1421 ///
1422 /// # let env = ExampleEnvironment::initialize("doctest_create_config_from_def")?;
1423 /// let config_mgr = env.get_config_manager()?;
1424 /// let config = config_mgr.create_config()?;
1425 /// let json = config.export()?;
1426 /// let config2 = config_mgr.create_config_from_definition(&json)?;
1427 /// # Ok::<(), SzError>(())
1428 /// ```
1429 ///
1430 /// # Errors
1431 ///
1432 /// * `SzError::BadInput` - Invalid JSON or configuration format
1433 fn create_config_from_definition(&self, config_definition: &str)
1434 -> SzResult<Box<dyn SzConfig>>;
1435
1436 /// Gets the configuration registry.
1437 ///
1438 /// Returns information about all registered configuration versions.
1439 ///
1440 /// # Returns
1441 ///
1442 /// JSON string with array of configuration metadata including IDs, comments, and timestamps.
1443 ///
1444 /// # Examples
1445 ///
1446 /// ```
1447 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1448 /// use sz_rust_sdk::prelude::*;
1449 ///
1450 /// # let env = ExampleEnvironment::initialize("doctest_get_config_registry")?;
1451 /// let config_mgr = env.get_config_manager()?;
1452 /// let registry = config_mgr.get_config_registry()?;
1453 /// println!("Registered configs: {}", registry);
1454 /// # Ok::<(), SzError>(())
1455 /// ```
1456 fn get_config_registry(&self) -> SzResult<JsonString>;
1457
1458 /// Gets the currently active default configuration ID.
1459 ///
1460 /// # Returns
1461 ///
1462 /// The configuration ID that is currently active for entity resolution.
1463 ///
1464 /// # Examples
1465 ///
1466 /// ```
1467 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1468 /// use sz_rust_sdk::prelude::*;
1469 ///
1470 /// # let env = ExampleEnvironment::initialize("doctest_get_default_config_id")?;
1471 /// let config_mgr = env.get_config_manager()?;
1472 /// let config_id = config_mgr.get_default_config_id()?;
1473 /// println!("Default config ID: {}", config_id);
1474 /// # Ok::<(), SzError>(())
1475 /// ```
1476 fn get_default_config_id(&self) -> SzResult<ConfigId>;
1477
1478 /// Registers a new configuration version.
1479 ///
1480 /// Saves a configuration to the repository, making it available for activation.
1481 /// Does not activate the configuration - use `set_default_config_id` for that.
1482 ///
1483 /// # Arguments
1484 ///
1485 /// * `config_definition` - JSON string from `SzConfig::export()`
1486 /// * `config_comment` - Optional description for this configuration version
1487 ///
1488 /// # Returns
1489 ///
1490 /// The assigned configuration ID for the newly registered configuration.
1491 ///
1492 /// # Examples
1493 ///
1494 /// ```
1495 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1496 /// use sz_rust_sdk::prelude::*;
1497 ///
1498 /// # let env = ExampleEnvironment::initialize("doctest_register_config")?;
1499 /// let config_mgr = env.get_config_manager()?;
1500 /// let config = config_mgr.create_config()?;
1501 /// let config_json = config.export()?;
1502 /// let config_id = config_mgr.register_config(&config_json, Some("Test config"))?;
1503 /// println!("Registered config ID: {}", config_id);
1504 /// # Ok::<(), SzError>(())
1505 /// ```
1506 fn register_config(
1507 &self,
1508 config_definition: &str,
1509 config_comment: Option<&str>,
1510 ) -> SzResult<ConfigId>;
1511
1512 /// Atomically replaces the default configuration ID.
1513 ///
1514 /// Updates the active configuration only if the current default matches
1515 /// the expected value. This prevents race conditions when multiple processes
1516 /// may be updating the configuration.
1517 ///
1518 /// # Arguments
1519 ///
1520 /// * `current_default_config_id` - Expected current default (for optimistic locking)
1521 /// * `new_default_config_id` - New configuration to activate
1522 ///
1523 /// # Examples
1524 ///
1525 /// ```
1526 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1527 /// use sz_rust_sdk::prelude::*;
1528 ///
1529 /// # let env = ExampleEnvironment::initialize("doctest_replace_default_config_id")?;
1530 /// let config_mgr = env.get_config_manager()?;
1531 /// let current_id = config_mgr.get_default_config_id()?;
1532 /// let config = config_mgr.create_config()?;
1533 /// let config_json = config.export()?;
1534 /// let new_id = config_mgr.register_config(&config_json, Some("Replacement config"))?;
1535 /// config_mgr.replace_default_config_id(current_id, new_id)?;
1536 /// # Ok::<(), SzError>(())
1537 /// ```
1538 ///
1539 /// # Errors
1540 ///
1541 /// * `SzError::ReplaceConflict` - Current default doesn't match expected value
1542 /// * `SzError::NotFound` - New configuration ID does not exist
1543 fn replace_default_config_id(
1544 &self,
1545 current_default_config_id: ConfigId,
1546 new_default_config_id: ConfigId,
1547 ) -> SzResult<()>;
1548
1549 /// Registers and activates a configuration in one operation.
1550 ///
1551 /// Convenience method that combines `register_config` and `set_default_config_id`.
1552 ///
1553 /// # Arguments
1554 ///
1555 /// * `config_definition` - JSON string from `SzConfig::export()`
1556 /// * `config_comment` - Optional description for this configuration version
1557 ///
1558 /// # Returns
1559 ///
1560 /// The assigned configuration ID.
1561 ///
1562 /// # Examples
1563 ///
1564 /// ```
1565 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1566 /// use sz_rust_sdk::prelude::*;
1567 ///
1568 /// # let env = ExampleEnvironment::initialize("doctest_set_default_config")?;
1569 /// let config_mgr = env.get_config_manager()?;
1570 /// let config = config_mgr.create_config()?;
1571 /// let config_json = config.export()?;
1572 /// let config_id = config_mgr.set_default_config(&config_json, Some("New default"))?;
1573 /// println!("New default config ID: {}", config_id);
1574 /// # Ok::<(), SzError>(())
1575 /// ```
1576 fn set_default_config(
1577 &self,
1578 config_definition: &str,
1579 config_comment: Option<&str>,
1580 ) -> SzResult<ConfigId>;
1581
1582 /// Sets the active configuration by ID.
1583 ///
1584 /// Activates a previously registered configuration. The engine will use
1585 /// this configuration for all subsequent operations.
1586 ///
1587 /// # Arguments
1588 ///
1589 /// * `config_id` - ID of a registered configuration to activate
1590 ///
1591 /// # Examples
1592 ///
1593 /// ```
1594 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1595 /// use sz_rust_sdk::prelude::*;
1596 ///
1597 /// # let env = ExampleEnvironment::initialize("doctest_set_default_config_id")?;
1598 /// let config_mgr = env.get_config_manager()?;
1599 /// let config_id = config_mgr.get_default_config_id()?;
1600 /// config_mgr.set_default_config_id(config_id)?;
1601 /// # Ok::<(), SzError>(())
1602 /// ```
1603 ///
1604 /// # Errors
1605 ///
1606 /// * `SzError::NotFound` - Configuration ID does not exist
1607 fn set_default_config_id(&self, config_id: ConfigId) -> SzResult<()>;
1608}
1609
1610/// System diagnostics and monitoring.
1611///
1612/// The `SzDiagnostic` trait provides methods for system health monitoring,
1613/// performance analysis, and repository maintenance.
1614///
1615/// # Obtaining an Instance
1616///
1617/// ```
1618/// # use sz_rust_sdk::helpers::ExampleEnvironment;
1619/// # let env = ExampleEnvironment::initialize("doctest_sz_diagnostic")?;
1620/// use sz_rust_sdk::prelude::*;
1621///
1622/// let diagnostic = env.get_diagnostic()?;
1623/// # Ok::<(), SzError>(())
1624/// ```
1625pub trait SzDiagnostic: Send + Sync {
1626 /// Runs a performance benchmark on the repository.
1627 ///
1628 /// Executes read operations against the repository to measure performance
1629 /// characteristics. Useful for baseline testing and capacity planning.
1630 ///
1631 /// # Arguments
1632 ///
1633 /// * `seconds_to_run` - Duration of the benchmark in seconds
1634 ///
1635 /// # Returns
1636 ///
1637 /// JSON string with performance metrics including operations per second.
1638 ///
1639 /// # Examples
1640 ///
1641 /// ```
1642 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1643 /// use sz_rust_sdk::prelude::*;
1644 ///
1645 /// # let env = ExampleEnvironment::initialize("doctest_check_repo_perf")?;
1646 /// let diagnostic = env.get_diagnostic()?;
1647 /// let result = diagnostic.check_repository_performance(1)?;
1648 /// println!("Performance: {}", result);
1649 /// # Ok::<(), SzError>(())
1650 /// ```
1651 ///
1652 /// # Errors
1653 ///
1654 /// * `SzError::BadInput` - Invalid duration (must be positive)
1655 fn check_repository_performance(&self, seconds_to_run: i64) -> SzResult<JsonString>;
1656
1657 /// Gets detailed information about a specific feature.
1658 ///
1659 /// Retrieves internal feature data useful for debugging entity resolution
1660 /// decisions. Features are the normalized attributes extracted from records.
1661 ///
1662 /// # Arguments
1663 ///
1664 /// * `feature_id` - Internal feature identifier
1665 ///
1666 /// # Returns
1667 ///
1668 /// JSON string with feature details including type, value, and usage statistics.
1669 ///
1670 /// # Examples
1671 ///
1672 /// ```no_run
1673 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1674 /// use sz_rust_sdk::prelude::*;
1675 ///
1676 /// # let env = ExampleEnvironment::initialize("doctest_get_feature")?;
1677 /// let diagnostic = env.get_diagnostic()?;
1678 /// let feature_id = 1; // obtained from entity resolution results
1679 /// let result = diagnostic.get_feature(feature_id)?;
1680 /// println!("Feature: {}", result);
1681 /// # Ok::<(), SzError>(())
1682 /// ```
1683 ///
1684 /// # Errors
1685 ///
1686 /// * `SzError::NotFound` - Feature ID does not exist
1687 fn get_feature(&self, feature_id: FeatureId) -> SzResult<JsonString>;
1688
1689 /// Gets repository statistics and information.
1690 ///
1691 /// Returns aggregate information about the entity repository including
1692 /// record counts, entity counts, and data source statistics.
1693 ///
1694 /// # Returns
1695 ///
1696 /// JSON string with repository statistics.
1697 ///
1698 /// # Examples
1699 ///
1700 /// ```
1701 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1702 /// use sz_rust_sdk::prelude::*;
1703 ///
1704 /// # let env = ExampleEnvironment::initialize("doctest_get_repository_info")?;
1705 /// let diagnostic = env.get_diagnostic()?;
1706 /// let info = diagnostic.get_repository_info()?;
1707 /// println!("Repository info: {}", info);
1708 /// # Ok::<(), SzError>(())
1709 /// ```
1710 fn get_repository_info(&self) -> SzResult<JsonString>;
1711
1712 /// Purges all entity data from the repository.
1713 ///
1714 /// Removes all records and entities while preserving configuration.
1715 /// Use with caution - this operation is irreversible.
1716 ///
1717 /// # Warning
1718 ///
1719 /// This permanently deletes all entity resolution data. Configuration
1720 /// and data source definitions are preserved.
1721 ///
1722 /// # Examples
1723 ///
1724 /// ```
1725 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1726 /// use sz_rust_sdk::prelude::*;
1727 ///
1728 /// # let env = ExampleEnvironment::initialize("doctest_purge_repository")?;
1729 /// let diagnostic = env.get_diagnostic()?;
1730 /// diagnostic.purge_repository()?;
1731 /// # Ok::<(), SzError>(())
1732 /// ```
1733 fn purge_repository(&self) -> SzResult<()>;
1734}
1735
1736/// Product version and license information.
1737///
1738/// The `SzProduct` trait provides methods for retrieving product version
1739/// and licensing information.
1740///
1741/// # Obtaining an Instance
1742///
1743/// ```
1744/// # use sz_rust_sdk::helpers::ExampleEnvironment;
1745/// # let env = ExampleEnvironment::initialize("doctest_sz_product")?;
1746/// use sz_rust_sdk::prelude::*;
1747///
1748/// let product = env.get_product()?;
1749/// # Ok::<(), SzError>(())
1750/// ```
1751pub trait SzProduct: Send + Sync {
1752 /// Gets the product license details.
1753 ///
1754 /// Returns information about the Senzing license including type,
1755 /// expiration, and feature entitlements.
1756 ///
1757 /// # Returns
1758 ///
1759 /// JSON string with license information.
1760 ///
1761 /// # Examples
1762 ///
1763 /// ```
1764 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1765 /// use sz_rust_sdk::prelude::*;
1766 ///
1767 /// # let env = ExampleEnvironment::initialize("doctest_get_license")?;
1768 /// let product = env.get_product()?;
1769 /// let license = product.get_license()?;
1770 /// println!("License: {}", license);
1771 /// # Ok::<(), SzError>(())
1772 /// ```
1773 fn get_license(&self) -> SzResult<JsonString>;
1774
1775 /// Gets the product version information.
1776 ///
1777 /// Returns version details for the Senzing engine and its components.
1778 ///
1779 /// # Returns
1780 ///
1781 /// JSON string with version information including build date and component versions.
1782 ///
1783 /// # Examples
1784 ///
1785 /// ```
1786 /// # use sz_rust_sdk::helpers::ExampleEnvironment;
1787 /// use sz_rust_sdk::prelude::*;
1788 ///
1789 /// # let env = ExampleEnvironment::initialize("doctest_get_version")?;
1790 /// let product = env.get_product()?;
1791 /// let version = product.get_version()?;
1792 /// println!("Version: {}", version);
1793 /// # Ok::<(), SzError>(())
1794 /// ```
1795 fn get_version(&self) -> SzResult<JsonString>;
1796}