sn0int 0.25.0

Semi-automatic OSINT framework and package manager
Documentation
use crate::errors::*;

use crate::engine::ctx::State;
use crate::geo::{self, Point};
use crate::hlua::{self, AnyLuaValue};
use std::sync::Arc;


pub fn geo_polygon_contains(lua: &mut hlua::Lua, state: Arc<dyn State>) {
    lua.set("geo_polygon_contains", hlua::function2(move |polygon: Vec<AnyLuaValue>, point: AnyLuaValue| -> Result<bool> {
        let polygon = polygon.into_iter()
            .map(Point::try_from)
            .collect::<Result<Vec<_>>>()
            .context("Invalid polygon")
            .map_err(|err| state.set_error(Error::from(err)))?;

        let point = Point::try_from(point)
            .context("Invalid point")
            .map_err(|err| state.set_error(Error::from(err)))?;

        Ok(geo::polygon_contains(&polygon, &point))
    }))
}

#[cfg(test)]
mod tests {
    use crate::engine::ctx::Script;

    fn hamburg_polygon() -> &'static str {
        "
            { lat=53.63975308945899,  lon=9.764785766601562  },
            { lat=53.59494998253459,  lon=9.827270507812     },
            { lat=53.663153974456456, lon=9.9151611328125    },
            { lat=53.65582987649682,  lon=9.976272583007812  },
            { lat=53.68613523817129,  lon=9.992752075195312  },
            { lat=53.68674518938816,  lon=10.051460266113281 },
            { lat=53.72495117617815,  lon=10.075492858886719 },
            { lat=53.71946627930625,  lon=10.118408203125    },
            { lat=53.743635083157756, lon=10.164413452148438 },
            { lat=53.73104466704585,  lon=10.202865600585938 },
            { lat=53.676781546441546, lon=10.16304016113281  },
            { lat=53.632832079199474, lon=10.235824584960938 },
            { lat=53.608803292930894, lon=10.2008056640625   },
            { lat=53.578646152866504, lon=10.208358764648438 },
            { lat=53.57212285981298,  lon=10.163726806640625 },
            { lat=53.52071674896369,  lon=10.18707275390625  },
            { lat=53.52643162253097,  lon=10.224151611328125 },
            { lat=53.44062753992289,  lon=10.347747802734375 },
            { lat=53.38824275010831,  lon=10.248870849609375 },
            { lat=53.38824275010831,  lon=10.15960693359375  },
            { lat=53.44635321212876,  lon=10.064849853515625 },
            { lat=53.40595029739904,  lon=9.985198974609375  },
            { lat=53.42385506057106,  lon=9.951210021972656  },
            { lat=53.41843327091211,  lon=9.944171905517578  },
            { lat=53.41812635648326,  lon=9.927349090576172  },
            { lat=53.412294561442884, lon=9.917736053466797  },
            { lat=53.41464783813818,  lon=9.901256561279297  },
            { lat=53.443490472483326, lon=9.912586212158201  },
            { lat=53.45177144115704,  lon=9.897651672363281  },
            { lat=53.43633277935392,  lon=9.866924285888672  },
            { lat=53.427639673754776, lon=9.866409301757812  },
            { lat=53.427639673754776, lon=9.858856201171875  },
            { lat=53.46710230573499,  lon=9.795513153076172  },
            { lat=53.49039461941655,  lon=9.795341491699219  },
            { lat=53.49029248806277,  lon=9.77903366088867   },
            { lat=53.49856433088649,  lon=9.780235290527344  },
            { lat=53.5078554643033,   lon=9.758434295654297  },
            { lat=53.545407634092975, lon=9.759807586669922  },
            { lat=53.568147234570084, lon=9.633293151855469  },
            { lat=53.58802162343514,  lon=9.655780792236328  },
            { lat=53.568351121879815, lon=9.727706909179688  },
            { lat=53.60921067445695,  lon=9.737663269042969  },
        "
    }

    #[test]
    fn verify_polygon_hamburg_contains_hamburg() {
        let script = Script::load_unchecked(format!(r#"
        function run()
            x = geo_polygon_contains({{{}}}, {{
                lat=53.551085,
                lon=9.993682,
            }})
            if last_err() then return end
            if not x then
                return 'hamburg should be in hamburg'
            end
        end
        "#, hamburg_polygon())).expect("Failed to load script");
        script.test().expect("Script failed");
    }

    #[test]
    fn verify_polygon_hamburg_not_contains_berlin() {
        let script = Script::load_unchecked(format!(r#"
        function run()
            x = geo_polygon_contains({{{}}}, {{
                lat=52.52437,
                lon=13.41053,
            }})
            if last_err() then return end
            if x then
                return 'berlin should not be in hamburg'
            end
        end
        "#, hamburg_polygon())).expect("Failed to load script");
        script.test().expect("Script failed");
    }

    #[test]
    fn verify_polygon_hamburg_not_contains_ny() {
        let script = Script::load_unchecked(format!(r#"
        function run()
            x = geo_polygon_contains({{{}}}, {{
                lat=40.726662,
                lon=-74.036677,
            }})
            if last_err() then return end
            if x then
                return 'ny should not be in hamburg'
            end
        end
        "#, hamburg_polygon())).expect("Failed to load script");
        script.test().expect("Script failed");
    }
}