use crate::datatypes::values::Value;
pub(super) const SPATIAL_RESOLUTION_HELP: &str =
"spatial argument did not resolve to a geometry or point. \
Either pass column_types={'<col>': 'geometry'} (or 'location.lat'/'location.lon') during \
add_nodes(), or store the data under a conventional property name (wkt_geometry, geometry, \
geom, or wkt for WKT; latitude+longitude or lat+lon for points).";
pub(super) fn json_to_value(j: &serde_json::Value) -> Value {
match j {
serde_json::Value::Null => Value::Null,
serde_json::Value::Bool(b) => Value::Boolean(*b),
serde_json::Value::Number(n) => {
if let Some(i) = n.as_i64() {
Value::Int64(i)
} else {
Value::Float64(n.as_f64().unwrap_or(f64::NAN))
}
}
serde_json::Value::String(s) => Value::String(s.clone()),
serde_json::Value::Array(a) => Value::List(a.iter().map(json_to_value).collect()),
serde_json::Value::Object(o) => Value::Map(
o.iter()
.map(|(k, v)| (k.clone(), json_to_value(v)))
.collect(),
),
}
}
#[derive(Clone, Copy)]
pub(super) enum LocalTemporalKind {
DateTime,
Time,
}
pub(super) fn next_random_u64() -> u64 {
use std::cell::Cell;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::SystemTime;
static THREAD_COUNTER: AtomicU64 = AtomicU64::new(0);
thread_local! {
static XORSHIFT_STATE: Cell<u64> = {
let nanos = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_nanos() as u64;
let counter = THREAD_COUNTER.fetch_add(1, Ordering::Relaxed);
let mut seed = nanos.wrapping_add(counter.wrapping_mul(0x9E37_79B9_7F4A_7C15));
seed ^= seed >> 30;
seed = seed.wrapping_mul(0xBF58_476D_1CE4_E5B9);
seed ^= seed >> 27;
seed = seed.wrapping_mul(0x94D0_49BB_1331_11EB);
seed ^= seed >> 31;
Cell::new(seed | 1)
};
}
XORSHIFT_STATE.with(|state| {
let mut x = state.get();
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
state.set(x);
x
})
}
pub(super) fn next_random_u128_halves() -> (u64, u64) {
(next_random_u64(), next_random_u64())
}
pub(super) fn coerce_naive_datetime(v: &Value) -> Option<chrono::NaiveDateTime> {
match v {
Value::Timestamp(dt) => Some(*dt),
Value::DateTime(d) => d.and_hms_opt(0, 0, 0),
_ => None,
}
}