pub mod core;
pub mod protocols;
pub mod sources;
pub mod gps;
pub mod network;
pub mod drift;
pub mod health;
pub mod quality;
pub mod statistics;
pub use core::{
ClockOffset, ClockSynchronizationConfig, ClockSynchronizationManager,
ClockSynchronizationState, ClockSynchronizationStatus, ClockSynchronizer, SynchronizationEvent,
SynchronizationResult,
};
pub use protocols::{
BerkeleyConfig, ClockSyncProtocol, CristianConfig, CustomProtocolConfig, NtpConfig,
NtpSynchronizer, ProtocolError, ProtocolManager, PtpConfig, PtpSynchronizer, SntpConfig,
SntpSynchronizer,
};
pub use sources::{
AtomicClockType, ClockSource, RadioTimeStation, SourceSelectionAlgorithm,
SourceSelectionCriteria, SourceValidation, SystemClockConfig, TimeSource, TimeSourceConfig,
TimeSourceManager,
};
pub use gps::{
AntennaConfig, GpsConfig, GpsError, GpsErrorCorrection, GpsReceiverType, GpsSignalProcessing,
GpsSynchronizationManager, GpsTime, IonosphericCorrection, SatelliteClockCorrection,
TroposphericCorrection,
};
pub use network::{
LoadBalancingAlgorithm, MessagePassingConfig, MessagePriority, NetworkFaultTolerance,
NetworkLoadBalancing, NetworkSyncConfig, NetworkSyncError, NetworkSynchronizationManager,
NetworkTopology, SyncMessageType,
};
pub use quality::{
ClockAccuracyRequirements, ClockQualityMonitor, QualityAssessment, QualityGrade, QualityMetric,
QualityMonitoringConfig, QualityRequirements, QualitySnapshot, QualityThresholds,
SourceQualityMonitoring,
};
pub use drift::{
DriftCompensationAlgorithm, DriftCompensationConfig, DriftCompensationError,
DriftCompensationStatus, DriftCompensator, DriftMeasurement, DriftMeasurementConfig,
DriftModel, DriftPredictionConfig, DriftPredictionEngine,
};
pub use health::{
AlertConfiguration, AlertSeverity, HealthAlert, HealthCheck, HealthCheckType,
HealthMonitorConfig, HealthMonitorError, HealthStatus, HealthThresholds, RecoveryConfiguration,
SourceFailoverConfig, SourceHealthMonitor,
};
pub use statistics::{
ClockStatistics, PerformanceHistory, PerformanceMeasurement, PerformanceReport,
PerformanceTracking, QualityReporting, ReliabilityStatistics, ReportGeneration,
StatisticsCollector, StatisticsError, TrendDirection,
};
pub type Result<T> = std::result::Result<T, ClockSynchronizationError>;
pub type Duration = std::time::Duration;
pub type Instant = std::time::Instant;
#[derive(Debug)]
pub enum ClockSynchronizationError {
CoreError(core::ClockSynchronizationError),
ProtocolError(protocols::ProtocolError),
SourceError(sources::SourceManagementError),
GpsError(gps::GpsError),
NetworkError(network::NetworkSyncError),
QualityError(quality::QualityMonitorError),
DriftError(drift::DriftCompensationError),
HealthError(health::HealthMonitorError),
StatisticsError(statistics::StatisticsError),
ConfigurationError(String),
SystemError(String),
}
impl std::fmt::Display for ClockSynchronizationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ClockSynchronizationError::CoreError(e) => {
write!(f, "Core synchronization error: {}", e)
}
ClockSynchronizationError::ProtocolError(e) => write!(f, "Protocol error: {}", e),
ClockSynchronizationError::SourceError(e) => {
write!(f, "Source management error: {}", e)
}
ClockSynchronizationError::GpsError(e) => write!(f, "GPS synchronization error: {}", e),
ClockSynchronizationError::NetworkError(e) => {
write!(f, "Network synchronization error: {}", e)
}
ClockSynchronizationError::QualityError(e) => {
write!(f, "Quality monitoring error: {}", e)
}
ClockSynchronizationError::DriftError(e) => {
write!(f, "Drift compensation error: {}", e)
}
ClockSynchronizationError::HealthError(e) => {
write!(f, "Health monitoring error: {}", e)
}
ClockSynchronizationError::StatisticsError(e) => write!(f, "Statistics error: {}", e),
ClockSynchronizationError::ConfigurationError(msg) => {
write!(f, "Configuration error: {}", msg)
}
ClockSynchronizationError::SystemError(msg) => write!(f, "System error: {}", msg),
}
}
}
impl std::error::Error for ClockSynchronizationError {}
impl From<core::ClockSynchronizationError> for ClockSynchronizationError {
fn from(err: core::ClockSynchronizationError) -> Self {
ClockSynchronizationError::CoreError(err)
}
}
impl From<protocols::ProtocolError> for ClockSynchronizationError {
fn from(err: protocols::ProtocolError) -> Self {
ClockSynchronizationError::ProtocolError(err)
}
}
impl From<sources::SourceManagementError> for ClockSynchronizationError {
fn from(err: sources::SourceManagementError) -> Self {
ClockSynchronizationError::SourceError(err)
}
}
impl From<gps::GpsError> for ClockSynchronizationError {
fn from(err: gps::GpsError) -> Self {
ClockSynchronizationError::GpsError(err)
}
}
impl From<network::NetworkSyncError> for ClockSynchronizationError {
fn from(err: network::NetworkSyncError) -> Self {
ClockSynchronizationError::NetworkError(err)
}
}
impl From<quality::QualityMonitorError> for ClockSynchronizationError {
fn from(err: quality::QualityMonitorError) -> Self {
ClockSynchronizationError::QualityError(err)
}
}
impl From<drift::DriftCompensationError> for ClockSynchronizationError {
fn from(err: drift::DriftCompensationError) -> Self {
ClockSynchronizationError::DriftError(err)
}
}
impl From<health::HealthMonitorError> for ClockSynchronizationError {
fn from(err: health::HealthMonitorError) -> Self {
ClockSynchronizationError::HealthError(err)
}
}
impl From<statistics::StatisticsError> for ClockSynchronizationError {
fn from(err: statistics::StatisticsError) -> Self {
ClockSynchronizationError::StatisticsError(err)
}
}
impl From<scirs2_core::CoreError> for ClockSynchronizationError {
fn from(err: scirs2_core::CoreError) -> Self {
ClockSynchronizationError::SystemError(err.to_string())
}
}
#[derive(Debug)]
pub struct ClockSynchronizationBuilder {
core_config: Option<core::ClockSynchronizationConfig>,
protocol_configs: Vec<protocols::ClockSyncProtocol>,
source_configs: Vec<sources::TimeSource>,
gps_config: Option<gps::GpsConfig>,
network_config: Option<network::NetworkSyncConfig>,
quality_config: Option<quality::QualityMonitoringConfig>,
drift_config: Option<drift::DriftCompensationConfig>,
health_config: Option<health::HealthMonitorConfig>,
statistics_config: Option<statistics::StatisticsCollectionConfig>,
}
impl ClockSynchronizationBuilder {
pub fn new() -> Self {
Self {
core_config: None,
protocol_configs: Vec::new(),
source_configs: Vec::new(),
gps_config: None,
network_config: None,
quality_config: None,
drift_config: None,
health_config: None,
statistics_config: None,
}
}
pub fn with_core_config(mut self, config: core::ClockSynchronizationConfig) -> Self {
self.core_config = Some(config);
self
}
pub fn with_protocol(mut self, protocol: protocols::ClockSyncProtocol) -> Self {
self.protocol_configs.push(protocol);
self
}
pub fn with_source(mut self, source: sources::TimeSource) -> Self {
self.source_configs.push(source);
self
}
pub fn with_gps_config(mut self, config: gps::GpsConfig) -> Self {
self.gps_config = Some(config);
self
}
pub fn with_network_config(mut self, config: network::NetworkSyncConfig) -> Self {
self.network_config = Some(config);
self
}
pub fn with_quality_config(mut self, config: quality::QualityMonitoringConfig) -> Self {
self.quality_config = Some(config);
self
}
pub fn with_drift_config(mut self, config: drift::DriftCompensationConfig) -> Self {
self.drift_config = Some(config);
self
}
pub fn with_health_config(mut self, config: health::HealthMonitorConfig) -> Self {
self.health_config = Some(config);
self
}
pub fn with_statistics_config(
mut self,
config: statistics::StatisticsCollectionConfig,
) -> Self {
self.statistics_config = Some(config);
self
}
pub fn build(self) -> Result<ClockSynchronizationManager> {
let core_config = self.core_config.unwrap_or_default();
let mut manager = ClockSynchronizationManager::new();
manager.config = core_config;
for protocol in self.protocol_configs {
manager.add_protocol(protocol)?;
}
for source in self.source_configs {
manager.add_time_source(source)?;
}
if let Some(gps_config) = self.gps_config {
manager.configure_gps(gps_config)?;
}
if let Some(network_config) = self.network_config {
manager.configure_network(network_config)?;
}
if let Some(quality_config) = self.quality_config {
manager.configure_quality_monitoring(quality_config)?;
}
if let Some(drift_config) = self.drift_config {
manager.configure_drift_compensation(drift_config)?;
}
if let Some(health_config) = self.health_config {
manager.configure_health_monitoring(health_config)?;
}
if let Some(statistics_config) = self.statistics_config {
manager.configure_statistics(statistics_config)?;
}
Ok(manager)
}
}
impl Default for ClockSynchronizationBuilder {
fn default() -> Self {
Self::new()
}
}
pub mod utils {
use super::*;
pub fn create_ntp_sync_manager(
ntp_servers: Vec<String>,
) -> Result<ClockSynchronizationManager> {
let mut builder = ClockSynchronizationBuilder::new();
builder = builder.with_protocol(protocols::ClockSyncProtocol::NTP);
let source_count = builder.source_configs.len();
for _ in 0..source_count {
let source = sources::TimeSource {
source_type: sources::ClockSource::NTP,
};
builder = builder.with_source(source);
}
builder = builder.with_quality_config(quality::QualityMonitoringConfig::default());
builder = builder.with_health_config(health::HealthMonitorConfig::default());
builder.build()
}
pub fn create_gps_sync_manager(
gps_config: gps::GpsConfig,
) -> Result<ClockSynchronizationManager> {
let mut builder = ClockSynchronizationBuilder::new();
builder = builder.with_gps_config(gps_config.clone());
let source = sources::TimeSource {
source_type: sources::ClockSource::GPS,
};
builder = builder.with_source(source);
builder = builder.with_quality_config(quality::QualityMonitoringConfig::default());
builder = builder.with_drift_config(drift::DriftCompensationConfig::default());
builder = builder.with_health_config(health::HealthMonitorConfig::default());
builder.build()
}
pub fn create_precision_sync_manager() -> Result<ClockSynchronizationManager> {
let mut builder = ClockSynchronizationBuilder::new();
builder = builder.with_protocol(protocols::ClockSyncProtocol::PTP);
let source = sources::TimeSource {
source_type: sources::ClockSource::Atomic,
};
builder = builder.with_source(source);
builder = builder.with_quality_config(quality::QualityMonitoringConfig::default());
builder = builder.with_drift_config(drift::DriftCompensationConfig::default());
builder = builder.with_health_config(health::HealthMonitorConfig::default());
builder = builder.with_statistics_config(statistics::StatisticsCollectionConfig::default());
builder.build()
}
pub fn duration_to_string(duration: Duration) -> String {
let total_seconds = duration.as_secs();
let days = total_seconds / 86400;
let hours = (total_seconds % 86400) / 3600;
let minutes = (total_seconds % 3600) / 60;
let seconds = total_seconds % 60;
let millis = duration.subsec_millis();
let micros = duration.subsec_micros() % 1000;
let nanos = duration.subsec_nanos() % 1000;
if days > 0 {
format!("{}d {}h {}m {}s", days, hours, minutes, seconds)
} else if hours > 0 {
format!("{}h {}m {}s", hours, minutes, seconds)
} else if minutes > 0 {
format!("{}m {}s", minutes, seconds)
} else if seconds > 0 {
format!("{}.{:03}s", seconds, millis)
} else if millis > 0 {
format!("{}.{:03}ms", millis, micros)
} else if micros > 0 {
format!("{}.{:03}μs", micros, nanos)
} else {
format!("{}ns", nanos)
}
}
pub fn validate_clock_offset(
offset: ClockOffset,
requirements: &quality::ClockAccuracyRequirements,
) -> bool {
offset.offset_ns.abs() as f64 <= requirements.max_drift_ppm
}
pub fn calculate_quality_score(metrics: &std::collections::HashMap<String, f64>) -> f64 {
if metrics.is_empty() {
return 0.0;
}
let sum: f64 = metrics.values().sum();
sum / metrics.len() as f64
}
pub fn get_system_uptime() -> Duration {
Duration::from_secs(86400) }
}
pub mod prelude {
pub use super::{
ClockOffset, ClockSynchronizationBuilder, ClockSynchronizationConfig,
ClockSynchronizationError, ClockSynchronizationManager, Result,
};
pub use super::health::{AlertSeverity, HealthCheckType};
pub use super::protocols::{ClockSyncProtocol, NtpConfig, PtpConfig};
pub use super::quality::{QualityGrade, QualityMetric, TrendDirection};
pub use super::sources::{AtomicClockType, ClockSource, TimeSource};
pub use super::statistics::{PerformanceMetric, ReportFormat};
pub use super::utils;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_builder_pattern() {
let builder =
ClockSynchronizationBuilder::new().with_protocol(protocols::ClockSyncProtocol::NTP);
assert!(builder.protocol_configs.len() == 1);
}
#[test]
fn test_error_conversions() {
let core_error = core::ClockSynchronizationError;
let sync_error: ClockSynchronizationError = core_error.into();
match sync_error {
ClockSynchronizationError::CoreError(_) => {}
_ => panic!("Error conversion failed"),
}
}
#[test]
fn test_utility_functions() {
let duration = Duration::from_millis(1500);
let formatted = utils::duration_to_string(duration);
assert!(formatted.contains("s"));
let mut metrics = std::collections::HashMap::new();
metrics.insert("accuracy".to_string(), 0.9);
metrics.insert("stability".to_string(), 0.8);
let score = utils::calculate_quality_score(&metrics);
assert!((score - 0.85).abs() < 1e-10);
}
}