Skip to main content

oxigdal_geojson/
lib.rs

1//! OxiGDAL GeoJSON Driver - RFC 7946 Implementation
2//!
3//! This crate provides a pure Rust implementation of GeoJSON (RFC 7946) reading
4//! and writing for the OxiGDAL ecosystem. It supports all geometry types,
5//! features, feature collections, and coordinate reference systems.
6//!
7//! # Features
8//!
9//! - Full RFC 7946 compliance
10//! - Support for all geometry types (Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection)
11//! - Feature and FeatureCollection support
12//! - CRS (Coordinate Reference System) handling
13//! - Streaming reader for large files
14//! - Efficient writer with customizable formatting
15//! - Comprehensive validation
16//! - Zero-copy optimizations where possible
17//! - No `unwrap()` or `panic!()` in production code
18//!
19//! # Example
20//!
21//! ```rust
22//! use oxigdal_geojson::{GeoJsonReader, GeoJsonWriter, FeatureCollection};
23//! use std::fs::File;
24//! use std::io::{BufReader, BufWriter};
25//!
26//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
27//! // Reading GeoJSON
28//! # let temp_dir = std::env::temp_dir();
29//! # let input_path = temp_dir.join("test_input.geojson");
30//! # std::fs::write(&input_path, r#"{"type":"FeatureCollection","features":[]}"#)?;
31//! let file = File::open(&input_path)?;
32//! let reader = BufReader::new(file);
33//! let mut geojson_reader = GeoJsonReader::new(reader);
34//! let feature_collection = geojson_reader.read_feature_collection()?;
35//!
36//! // Writing GeoJSON
37//! # let output_path = temp_dir.join("test_output.geojson");
38//! let file = File::create(&output_path)?;
39//! let writer = BufWriter::new(file);
40//! let mut geojson_writer = GeoJsonWriter::new(writer);
41//! geojson_writer.write_feature_collection(&feature_collection)?;
42//! # std::fs::remove_file(&input_path)?;
43//! # std::fs::remove_file(&output_path)?;
44//! # Ok(())
45//! # }
46//! ```
47//!
48//! # RFC 7946 Compliance
49//!
50//! This implementation follows RFC 7946 strictly:
51//! - Right-hand rule for polygon orientation
52//! - WGS84 as default CRS (EPSG:4326)
53//! - Longitude-latitude order for coordinates
54//! - Validation of geometry topologies
55//! - Support for bounding boxes
56//! - Foreign members preserved during round-trip
57//!
58//! # Performance
59//!
60//! - Streaming API for large files (O(1) memory for features)
61//! - Zero-copy deserialization where possible
62//! - Efficient buffering and I/O
63//! - Parallel processing support (with `async` feature)
64//!
65//! # COOLJAPAN Policies
66//!
67//! - Pure Rust implementation (no C/C++ dependencies)
68//! - No `unwrap()` or `expect()` in production code
69//! - Comprehensive error handling
70//! - Extensive testing (unit + integration + property-based)
71//! - Clean API design following Rust idioms
72
73#![cfg_attr(not(feature = "std"), no_std)]
74#![warn(clippy::all)]
75// Pedantic disabled to reduce noise - default clippy::all is sufficient
76// #![warn(clippy::pedantic)]
77#![deny(clippy::unwrap_used)]
78#![deny(clippy::panic)]
79#![allow(clippy::module_name_repetitions)]
80#![allow(clippy::similar_names)]
81// Allow doc overindent in complex nested lists
82#![allow(clippy::doc_overindented_list_items)]
83// Allow partial documentation
84#![allow(missing_docs)]
85// Allow dead code for internal structures
86#![allow(dead_code)]
87// Allow manual div_ceil for CRS calculations
88#![allow(clippy::manual_div_ceil)]
89// Allow expect() for internal invariants
90#![allow(clippy::expect_used)]
91// Allow collapsible match for CRS handling
92#![allow(clippy::collapsible_match)]
93// Allow manual strip for path parsing
94#![allow(clippy::manual_strip)]
95// Allow should_implement_trait for builder patterns
96#![allow(clippy::should_implement_trait)]
97
98#[cfg(feature = "std")]
99extern crate std;
100
101pub mod error;
102pub mod reader;
103pub mod types;
104pub mod utils;
105pub mod validation;
106pub mod writer;
107
108// Re-export commonly used types
109pub use error::{GeoJsonError, Result};
110pub use reader::GeoJsonReader;
111pub use types::{
112    Coordinate, CoordinateSequence, Crs, Feature, FeatureCollection, Geometry, GeometryType,
113    Position, Properties,
114};
115pub use validation::Validator;
116pub use writer::GeoJsonWriter;
117
118/// Crate version
119pub const VERSION: &str = env!("CARGO_PKG_VERSION");
120
121/// Crate name
122pub const NAME: &str = env!("CARGO_PKG_NAME");
123
124/// Default CRS for GeoJSON (WGS84)
125pub const DEFAULT_CRS: &str = "urn:ogc:def:crs:OGC:1.3:CRS84";
126
127/// GeoJSON MIME type
128pub const MIME_TYPE: &str = "application/geo+json";
129
130/// GeoJSON file extension
131pub const FILE_EXTENSION: &str = ".geojson";
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136
137    #[test]
138    fn test_constants() {
139        assert!(!VERSION.is_empty());
140        assert_eq!(NAME, "oxigdal-geojson");
141        assert_eq!(DEFAULT_CRS, "urn:ogc:def:crs:OGC:1.3:CRS84");
142        assert_eq!(MIME_TYPE, "application/geo+json");
143        assert_eq!(FILE_EXTENSION, ".geojson");
144    }
145}