perfect-postcode/server-rs/src/data.rs
2026-07-12 20:37:39 +01:00

83 lines
3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

mod actual_listings;
pub mod area_crime_averages;
pub mod crime_by_year;
pub mod crime_records;
mod developments;
mod places;
mod poi;
pub mod postcode_population;
mod postcodes;
mod property;
pub mod spill;
pub mod travel_time;
/// Apostrophe-like code points that should be elided (not treated as word breaks) when
/// normalizing search text. Keyboards, autocorrect and copy-paste all produce different glyphs
/// for what users mean as an apostrophe; treating any of them as a separator turns "King's Cross"
/// into the tokens `king s cross` and breaks matching. Covers the straight ASCII apostrophe, the
/// typographic left/right single quotes, grave/acute accents, the modifier-letter apostrophes,
/// prime, and the fullwidth apostrophe.
pub(crate) fn is_apostrophe(ch: char) -> bool {
matches!(
ch,
'\u{0027}' // ' APOSTROPHE
| '\u{0060}' // ` GRAVE ACCENT
| '\u{00B4}' // ´ ACUTE ACCENT
| '\u{02B9}' // ʹ MODIFIER LETTER PRIME
| '\u{02BB}' // ʻ MODIFIER LETTER TURNED COMMA (ʻokina)
| '\u{02BC}' // ʼ MODIFIER LETTER APOSTROPHE
| '\u{2018}' // ' LEFT SINGLE QUOTATION MARK
| '\u{2019}' // ' RIGHT SINGLE QUOTATION MARK
| '\u{201B}' // SINGLE HIGH-REVERSED-9 QUOTATION MARK
| '\u{2032}' // PRIME
| '\u{FF07}' // FULLWIDTH APOSTROPHE
)
}
fn panic_payload_message(payload: &(dyn std::any::Any + Send)) -> String {
if let Some(message) = payload.downcast_ref::<&'static str>() {
(*message).to_string()
} else if let Some(message) = payload.downcast_ref::<String>() {
message.clone()
} else {
"unknown panic payload".to_string()
}
}
pub(super) fn run_polars_io<T, F>(work: F) -> anyhow::Result<T>
where
T: Send,
F: FnOnce() -> anyhow::Result<T> + Send,
{
if tokio::runtime::Handle::try_current().is_err() {
return work();
}
std::thread::scope(|scope| {
scope.spawn(work).join().map_err(|payload| {
anyhow::anyhow!(
"Polars worker thread panicked: {}",
panic_payload_message(payload.as_ref())
)
})?
})
}
pub use actual_listings::{ActualListing, ActualListingData};
pub use area_crime_averages::AreaCrimeAverages;
pub use crime_by_year::CrimeByYearData;
pub use crime_records::CrimeRecords;
pub use developments::{DevelopmentData, DevelopmentSite};
pub use places::{
compute_trigrams, normalize_search_text, place_alias_tokens, trigram_similarity, PlaceData,
};
pub use poi::{resolve_poi_category_filter, POICategoryGroup, POIData, SchoolMetadata};
pub use postcode_population::PostcodePopulation;
pub use postcodes::{OutcodeData, PostcodeData};
pub use property::{
combine_nearest_distances, combined_station_feature_name,
combined_station_source_feature_names, precompute_h3, FeatureStats, Histogram, HistoricalPrice,
PostcodePoiMetrics, PropertyData, QuantRef, RenovationEvent, TenureEvent,
COMBINED_STATION_CATEGORY,
};
pub use travel_time::{slugify, TravelTimeStore};