Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_datime/tests/database_integration_demo.rs

22.0 KiB, 4 runs

created by r1870400018:8646, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\
2//! Anthropic Claude
3
4use oxedyne_fe2o3_datime::{
5 time::{CalClock, CalClockZone},
6 clock::ClockTime,
7 calendar::CalendarDate,
8 database::{
9 DatabaseStorable, DatabaseRecord, StorageFormat,
10 SqlCompatible, NoSqlDocument, IndexGenerator,
11 DatabaseIndex, IndexType,
12 },
13};
14
15use oxedyne_fe2o3_core::prelude::*;
16use oxedyne_fe2o3_jdat::prelude::*;
17
18use std::collections::HashMap;
19
20#[test]
21fn test_calclock_database_storage_binary() -> Outcome<()> {
22 let zone = CalClockZone::utc();
23 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
24
25 // Convert to binary database record
26 let record = res!(calclock.to_database_record(StorageFormat::Binary));
27 assert_eq!(record.storage_format, StorageFormat::Binary);
28 assert_eq!(record.get_metadata("type"), Some(&"CalClock".to_string()));
29 assert_eq!(record.get_metadata("timezone"), Some(&"UTC".to_string()));
30
31 // Verify binary format structure
32 if let Dat::Tup2(arr) = &record.primary_data {
33 let nanos_dat = &arr[0];
34 let zone_dat = &arr[1];
35 // Just verify types match expected patterns
36 if let Dat::I64(_) = nanos_dat { } else { panic!("Expected I64"); }
37 if let Dat::Str(zone_str) = zone_dat { assert_eq!(zone_str, "UTC"); } else { panic!("Expected Str"); }
38 } else {
39 return Err(err!("Invalid binary format structure"; Invalid));
40 }
41
42 // Round-trip conversion
43 let restored = res!(CalClock::from_database_record(&record));
44 assert_eq!(calclock, restored);
45
46 println!("✓ CalClock binary storage test passed");
47 Ok(())
48}
49
50#[test]
51fn test_calclock_database_storage_iso8601() -> Outcome<()> {
52 let zone = CalClockZone::utc();
53 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
54
55 // Convert to ISO 8601 database record
56 let record = res!(calclock.to_database_record(StorageFormat::Iso8601));
57 assert_eq!(record.storage_format, StorageFormat::Iso8601);
58
59 // Verify ISO format
60 if let Dat::Str(iso_string) = &record.primary_data {
61 assert!(iso_string.contains("2024-06-15"));
62 assert!(iso_string.contains("14:30:45"));
63 println!("ISO 8601 format: {}", iso_string);
64 } else {
65 return Err(err!("Invalid ISO format structure"; Invalid));
66 }
67
68 // Round-trip conversion
69 let restored = res!(CalClock::from_database_record(&record));
70 assert_eq!(calclock, restored);
71
72 println!("✓ CalClock ISO 8601 storage test passed");
73 Ok(())
74}
75
76#[test]
77fn test_calclock_database_storage_component() -> Outcome<()> {
78 let zone = CalClockZone::utc();
79 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
80
81 // Convert to component database record
82 let record = res!(calclock.to_database_record(StorageFormat::Component));
83 assert_eq!(record.storage_format, StorageFormat::Component);
84
85 // Verify component format
86 if let Dat::Map(components) = &record.primary_data {
87 assert_eq!(res!(components.get(&Dat::Str("year".to_string())).unwrap().get_i32().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 2024);
88 assert_eq!(res!(components.get(&Dat::Str("month".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 6);
89 assert_eq!(res!(components.get(&Dat::Str("day".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 15);
90 assert_eq!(res!(components.get(&Dat::Str("hour".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 14);
91 assert_eq!(res!(components.get(&Dat::Str("minute".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 30);
92 assert_eq!(res!(components.get(&Dat::Str("second".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 45);
93 assert_eq!(res!(components.get(&Dat::Str("nanosecond".to_string())).unwrap().get_u32().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 123_456_789);
94 assert_eq!(res!(components.get(&Dat::Str("timezone".to_string())).unwrap().get_string().ok_or_else(|| err!("Invalid type"; Invalid, Input))), "UTC");
95 } else {
96 return Err(err!("Invalid component format structure"; Invalid));
97 }
98
99 // Round-trip conversion
100 let restored = res!(CalClock::from_database_record(&record));
101 assert_eq!(calclock, restored);
102
103 println!("✓ CalClock component storage test passed");
104 Ok(())
105}
106
107#[test]
108fn test_calclock_database_storage_unix_timestamp() -> Outcome<()> {
109 let zone = CalClockZone::utc();
110 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123, zone));
111
112 // Convert to Unix timestamp database record
113 let record = res!(calclock.to_database_record(StorageFormat::UnixTimestamp));
114 assert_eq!(record.storage_format, StorageFormat::UnixTimestamp);
115
116 // Verify Unix timestamp format
117 if let Dat::Tup2(arr) = &record.primary_data {
118 let millis_dat = &arr[0];
119 let zone_dat = &arr[1];
120 // Just verify types match expected patterns
121 if let Dat::I64(_) = millis_dat { } else { panic!("Expected I64"); }
122 if let Dat::Str(zone_str) = zone_dat { assert_eq!(zone_str, "UTC"); } else { panic!("Expected Str"); }
123 } else {
124 return Err(err!("Invalid Unix timestamp format structure"; Invalid));
125 }
126
127 // Round-trip conversion
128 let restored = res!(CalClock::from_database_record(&record));
129 assert_eq!(calclock, restored);
130
131 println!("✓ CalClock Unix timestamp storage test passed");
132 Ok(())
133}
134
135#[test]
136fn test_database_record_indexes() -> Outcome<()> {
137 let zone = CalClockZone::utc();
138 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
139
140 let record = res!(calclock.to_database_record(StorageFormat::Binary));
141
142 // Verify indexes are created
143 assert!(record.get_index("year").is_some());
144 assert!(record.get_index("month").is_some());
145 assert!(record.get_index("day").is_some());
146 assert!(record.get_index("hour").is_some());
147 assert!(record.get_index("day_of_week").is_some());
148 assert!(record.get_index("timezone").is_some());
149
150 // Verify index values
151 assert_eq!(res!(record.get_index("year").unwrap().get_i32().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 2024);
152 assert_eq!(res!(record.get_index("month").unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 6);
153 assert_eq!(res!(record.get_index("day").unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 15);
154 assert_eq!(res!(record.get_index("hour").unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 14);
155 assert_eq!(res!(record.get_index("timezone").unwrap().get_string().ok_or_else(|| err!("Invalid type"; Invalid, Input))), "UTC");
156
157 println!("✓ Database record indexes test passed");
158 Ok(())
159}
160
161#[test]
162fn test_clock_time_database_storage() -> Outcome<()> {
163 let zone = CalClockZone::utc();
164 let time = res!(ClockTime::new(14, 30, 45, 123_456_789, zone));
165
166 // Test binary format
167 let record = res!(time.to_database_record(StorageFormat::Binary));
168 assert_eq!(record.storage_format, StorageFormat::Binary);
169
170 if let Dat::Tup2(arr) = &record.primary_data {
171 let nanos_dat = &arr[0];
172 let zone_dat = &arr[1];
173 // Just verify types match expected patterns
174 if let Dat::U64(_) = nanos_dat { } else { panic!("Expected U64"); }
175 if let Dat::Str(zone_str) = zone_dat { assert_eq!(zone_str, "UTC"); } else { panic!("Expected Str"); }
176 } else {
177 return Err(err!("Invalid binary format for ClockTime"; Invalid));
178 }
179
180 // Round-trip conversion
181 let restored = res!(ClockTime::from_database_record(&record));
182 assert_eq!(time, restored);
183
184 // Test component format
185 let component_record = res!(time.to_database_record(StorageFormat::Component));
186 if let Dat::Map(components) = &component_record.primary_data {
187 assert_eq!(res!(components.get(&Dat::Str("hour".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 14);
188 assert_eq!(res!(components.get(&Dat::Str("minute".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 30);
189 assert_eq!(res!(components.get(&Dat::Str("second".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 45);
190 assert_eq!(res!(components.get(&Dat::Str("nanosecond".to_string())).unwrap().get_u32().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 123_456_789);
191 } else {
192 return Err(err!("Invalid component format for ClockTime"; Invalid));
193 }
194
195 println!("✓ ClockTime database storage test passed");
196 Ok(())
197}
198
199#[test]
200fn test_calendar_date_database_storage() -> Outcome<()> {
201 let zone = CalClockZone::utc();
202 let date = res!(CalendarDate::new(2024, 6, 15, zone));
203
204 // Test binary format (Julian day)
205 let record = res!(date.to_database_record(StorageFormat::Binary));
206 assert_eq!(record.storage_format, StorageFormat::Binary);
207
208 if let Dat::Tup2(arr) = &record.primary_data {
209 let julian_dat = &arr[0];
210 let zone_dat = &arr[1];
211 // Just verify types match expected patterns
212 if let Dat::I64(_) = julian_dat { } else { panic!("Expected I64"); }
213 if let Dat::Str(zone_str) = zone_dat { assert_eq!(zone_str, "UTC"); } else { panic!("Expected Str"); }
214 } else {
215 return Err(err!("Invalid binary format for CalendarDate"; Invalid));
216 }
217
218 // Round-trip conversion
219 let restored = res!(CalendarDate::from_database_record(&record));
220 assert_eq!(date, restored);
221
222 // Test component format
223 let component_record = res!(date.to_database_record(StorageFormat::Component));
224 if let Dat::Map(components) = &component_record.primary_data {
225 assert_eq!(res!(components.get(&Dat::Str("year".to_string())).unwrap().get_i32().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 2024);
226 assert_eq!(res!(components.get(&Dat::Str("month".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 6);
227 assert_eq!(res!(components.get(&Dat::Str("day".to_string())).unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 15);
228 } else {
229 return Err(err!("Invalid component format for CalendarDate"; Invalid));
230 }
231
232 println!("✓ CalendarDate database storage test passed");
233 Ok(())
234}
235
236#[test]
237fn test_sql_compatibility() -> Outcome<()> {
238 // Test SQL data types
239 assert_eq!(CalClock::sql_data_type(StorageFormat::Binary), "BIGINT, VARCHAR(50)");
240 assert_eq!(ClockTime::sql_data_type(StorageFormat::Iso8601), "TIME");
241 assert_eq!(CalendarDate::sql_data_type(StorageFormat::Component), "JSONB");
242
243 // Test SQL table creation
244 let create_table_sql = CalClock::sql_create_table("events", StorageFormat::Binary);
245 assert!(create_table_sql.contains("CREATE TABLE events"));
246 assert!(create_table_sql.contains("timestamp_nanos BIGINT NOT NULL"));
247 assert!(create_table_sql.contains("timezone VARCHAR(50) NOT NULL"));
248 assert!(create_table_sql.contains("year INTEGER NOT NULL"));
249
250 // Test SQL index creation
251 let indexes = CalClock::sql_create_indexes("events");
252 assert!(!indexes.is_empty());
253 assert!(indexes.iter().any(|idx| idx.contains("timestamp_nanos")));
254 assert!(indexes.iter().any(|idx| idx.contains("timezone")));
255
256 // Test SQL values conversion
257 let zone = CalClockZone::utc();
258 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
259 let sql_values = res!(calclock.to_sql_values(StorageFormat::Binary));
260
261 assert!(sql_values.contains_key("timestamp_nanos"));
262 assert!(sql_values.contains_key("timezone"));
263 assert!(sql_values.contains_key("year"));
264 assert_eq!(sql_values.get("year"), Some(&"2024".to_string()));
265 assert_eq!(sql_values.get("timezone"), Some(&"'UTC'".to_string()));
266
267 // Test query fragments
268 let fragments = CalClock::sql_query_fragments();
269 assert!(!fragments.is_empty());
270 assert!(fragments.iter().any(|(name, _)| *name == "date_range"));
271 assert!(fragments.iter().any(|(name, _)| *name == "timezone_filter"));
272
273 println!("✓ SQL compatibility test passed");
274 Ok(())
275}
276
277#[test]
278fn test_nosql_document_format() -> Outcome<()> {
279 let zone = CalClockZone::utc();
280 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
281
282 // Convert to document format
283 let document = calclock.to_document();
284
285 // Verify document structure
286 assert!(document.contains_key("timestamp_nanos"));
287 assert!(document.contains_key("timestamp_millis"));
288 assert!(document.contains_key("year"));
289 assert!(document.contains_key("month"));
290 assert!(document.contains_key("day"));
291 assert!(document.contains_key("hour"));
292 assert!(document.contains_key("minute"));
293 assert!(document.contains_key("second"));
294 assert!(document.contains_key("nanosecond"));
295 assert!(document.contains_key("timezone"));
296 assert!(document.contains_key("iso_string"));
297 assert!(document.contains_key("is_leap_second"));
298 assert!(document.contains_key("is_weekend"));
299
300 // Verify values
301 assert_eq!(res!(document.get("year").unwrap().get_i32().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 2024);
302 assert_eq!(res!(document.get("month").unwrap().get_u8().ok_or_else(|| err!("Invalid type"; Invalid, Input))), 6);
303 assert_eq!(res!(document.get("timezone").unwrap().get_string().ok_or_else(|| err!("Invalid type"; Invalid, Input))), "UTC");
304
305 // Round-trip conversion
306 let restored = res!(CalClock::from_document(&document));
307 assert_eq!(calclock, restored);
308
309 // Test index fields
310 let index_fields = CalClock::index_fields();
311 assert!(!index_fields.is_empty());
312 assert!(index_fields.contains(&"timestamp_nanos"));
313 assert!(index_fields.contains(&"year"));
314 assert!(index_fields.contains(&"timezone"));
315
316 // Test compound indexes
317 let compound_indexes = CalClock::compound_indexes();
318 assert!(!compound_indexes.is_empty());
319 assert!(compound_indexes.iter().any(|idx| idx == &vec!["year", "month", "day"]));
320 assert!(compound_indexes.iter().any(|idx| idx == &vec!["timezone", "year"]));
321
322 println!("✓ NoSQL document format test passed");
323 Ok(())
324}
325
326#[test]
327fn test_database_index_generation() -> Outcome<()> {
328 let zone = CalClockZone::utc();
329 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
330
331 // Generate indexes
332 let indexes = calclock.generate_indexes("events");
333 assert!(!indexes.is_empty());
334
335 // Verify high-priority indexes exist
336 let critical_indexes = calclock.critical_indexes("events");
337 assert!(!critical_indexes.is_empty());
338
339 // Find timestamp index
340 let timestamp_index = indexes.iter()
341 .find(|idx| idx.name.contains("timestamp_nanos"))
342 .expect("Timestamp index should exist");
343 assert_eq!(timestamp_index.priority, 10); // Highest priority
344 assert_eq!(timestamp_index.fields, vec!["timestamp_nanos".to_string()]);
345
346 // Find date composite index
347 let date_index = indexes.iter()
348 .find(|idx| idx.name.contains("date") && idx.fields.len() == 3)
349 .expect("Date composite index should exist");
350 assert_eq!(date_index.fields, vec!["year".to_string(), "month".to_string(), "day".to_string()]);
351
352 // Test SQL generation
353 let sql = timestamp_index.to_sql("events");
354 assert!(sql.contains("CREATE"));
355 assert!(sql.contains("INDEX"));
356 assert!(sql.contains("events"));
357 assert!(sql.contains("timestamp_nanos"));
358
359 // Test MongoDB generation
360 let (spec, options) = timestamp_index.to_mongodb();
361 assert!(spec.contains_key("timestamp_nanos"));
362 assert!(options.contains_key("name"));
363
364 println!("✓ Database index generation test passed");
365 Ok(())
366}
367
368#[test]
369fn test_query_specific_indexes() -> Outcome<()> {
370 let zone = CalClockZone::utc();
371 let calclock = res!(CalClock::new(2024, 6, 15, 14, 30, 45, 123_456_789, zone));
372
373 // Generate indexes for specific query patterns
374 let query_patterns = vec![
375 "time_range_queries",
376 "calendar_navigation",
377 "timezone_aware",
378 "hourly_analytics",
379 "weekly_patterns",
380 "recent_data",
381 ];
382
383 let indexes = calclock.generate_query_specific_indexes("events", &query_patterns);
384 assert!(!indexes.is_empty());
385
386 // Verify specific indexes
387 let time_range_index = indexes.iter()
388 .find(|idx| idx.name.contains("time_range"))
389 .expect("Time range index should exist");
390 assert!(time_range_index.fields.contains(&"timestamp_nanos".to_string()));
391
392 let calendar_nav_index = indexes.iter()
393 .find(|idx| idx.name.contains("calendar_nav"))
394 .expect("Calendar navigation index should exist");
395 assert_eq!(calendar_nav_index.fields.len(), 3); // year, month, day
396
397 println!("✓ Query-specific indexes test passed");
398 Ok(())
399}
400
401#[test]
402fn test_storage_format_recommendations() -> Outcome<()> {
403 // Test recommended storage formats
404 assert_eq!(CalClock::recommended_storage_format(), StorageFormat::Binary);
405 assert_eq!(ClockTime::recommended_storage_format(), StorageFormat::Binary);
406 assert_eq!(CalendarDate::recommended_storage_format(), StorageFormat::Binary);
407
408 println!("✓ Storage format recommendations test passed");
409 Ok(())
410}
411
412#[test]
413fn test_database_record_metadata() -> Outcome<()> {
414 let zone = CalClockZone::utc();
415 let calclock = res!(CalClock::new(2024, 6, 15, 23, 59, 60, 0, zone)); // Leap second
416
417 let record = res!(calclock.to_database_record(StorageFormat::Binary));
418
419 // Verify metadata
420 assert_eq!(record.get_metadata("type"), Some(&"CalClock".to_string()));
421 assert_eq!(record.get_metadata("timezone"), Some(&"UTC".to_string()));
422 assert_eq!(record.get_metadata("leap_second"), Some(&"true".to_string()));
423
424 // Test adding custom metadata
425 let mut custom_record = record.clone();
426 custom_record.add_metadata("source", "user_input");
427 custom_record.add_metadata("processed", "2024-06-15");
428
429 assert_eq!(custom_record.get_metadata("source"), Some(&"user_input".to_string()));
430 assert_eq!(custom_record.get_metadata("processed"), Some(&"2024-06-15".to_string()));
431
432 println!("✓ Database record metadata test passed");
433 Ok(())
434}
435
436#[test]
437fn test_database_index_types() -> Outcome<()> {
438 // Test different index types
439 let btree_index = DatabaseIndex::new(
440 "test_btree",
441 vec!["timestamp".to_string()],
442 IndexType::BTree,
443 );
444
445 let hash_index = DatabaseIndex::new(
446 "test_hash",
447 vec!["timezone".to_string()],
448 IndexType::Hash,
449 );
450
451 let partial_index = DatabaseIndex::new(
452 "test_partial",
453 vec!["is_weekend".to_string()],
454 IndexType::Partial("is_weekend = TRUE".to_string()),
455 ).condition("is_weekend = TRUE");
456
457 let composite_index = DatabaseIndex::new(
458 "test_composite",
459 vec!["year".to_string(), "month".to_string()],
460 IndexType::Composite(vec!["year".to_string(), "month".to_string()]),
461 );
462
463 // Test SQL generation for different types
464 let btree_sql = btree_index.to_sql("test_table");
465 assert!(btree_sql.contains("USING BTREE"));
466
467 let hash_sql = hash_index.to_sql("test_table");
468 assert!(hash_sql.contains("USING HASH"));
469
470 let partial_sql = partial_index.to_sql("test_table");
471 assert!(partial_sql.contains("WHERE is_weekend = TRUE"));
472
473 let composite_sql = composite_index.to_sql("test_table");
474 assert!(composite_sql.contains("year, month"));
475
476 println!("✓ Database index types test passed");
477 Ok(())
478}
479
480pub fn test_database_integration(filter: &str) -> Outcome<()> {
481 println!("=== Database Integration Demo ===");
482
483 res!(test_it(filter, &["calclock_binary", "all", "database", "binary"], || {
484 test_calclock_database_storage_binary()
485 }));
486
487 res!(test_it(filter, &["calclock_iso", "all", "database", "iso"], || {
488 test_calclock_database_storage_iso8601()
489 }));
490
491 res!(test_it(filter, &["calclock_component", "all", "database", "component"], || {
492 test_calclock_database_storage_component()
493 }));
494
495 res!(test_it(filter, &["calclock_unix", "all", "database", "unix"], || {
496 test_calclock_database_storage_unix_timestamp()
497 }));
498
499 res!(test_it(filter, &["record_indexes", "all", "database", "indexes"], || {
500 test_database_record_indexes()
501 }));
502
503 res!(test_it(filter, &["clocktime_storage", "all", "database", "clocktime"], || {
504 test_clock_time_database_storage()
505 }));
506
507 res!(test_it(filter, &["caldate_storage", "all", "database", "caldate"], || {
508 test_calendar_date_database_storage()
509 }));
510
511 res!(test_it(filter, &["sql_compat", "all", "database", "sql"], || {
512 test_sql_compatibility()
513 }));
514
515 res!(test_it(filter, &["nosql_document", "all", "database", "nosql"], || {
516 test_nosql_document_format()
517 }));
518
519 res!(test_it(filter, &["index_generation", "all", "database", "generation"], || {
520 test_database_index_generation()
521 }));
522
523 res!(test_it(filter, &["query_indexes", "all", "database", "query"], || {
524 test_query_specific_indexes()
525 }));
526
527 res!(test_it(filter, &["format_recommendations", "all", "database", "recommendations"], || {
528 test_storage_format_recommendations()
529 }));
530
531 res!(test_it(filter, &["record_metadata", "all", "database", "metadata"], || {
532 test_database_record_metadata()
533 }));
534
535 res!(test_it(filter, &["index_types", "all", "database", "types"], || {
536 test_database_index_types()
537 }));
538
539 println!("✓ All database integration tests passed!");
540 Ok(())
541}
542
543fn test_it<F>(filter: &str, keywords: &[&str], test_fn: F) -> Outcome<()>
544where
545 F: FnOnce() -> Outcome<()>,
546{
547 if keywords.iter().any(|&kw| filter.contains(kw)) {
548 test_fn()
549 } else {
550 Ok(())
551 }
552}