rustis 0.19.3

Redis async driver for Rust
Documentation
use crate::{
    Result,
    commands::{
        GenericCommands, GeoAddCondition, GeoCommands, GeoSearchBy, GeoSearchFrom,
        GeoSearchOptions, GeoSearchOrder, GeoSearchResult, GeoSearchStoreOptions, GeoUnit,
    },
    tests::get_test_client,
};
use serial_test::serial;

#[cfg_attr(feature = "tokio-runtime", tokio::test)]
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
#[serial]
async fn geoadd() -> Result<()> {
    let client = get_test_client().await?;

    // cleanup
    client.del("key").await?;

    let len = client
        .geoadd(
            "key",
            None,
            false,
            [(1.0, 1.0, "location1"), (2.0, 2.0, "location2")],
        )
        .await?;
    assert_eq!(2, len);

    let len = client
        .geoadd(
            "key",
            None,
            false,
            [(1.0, 1.0, "location1"), (2.0, 2.0, "location2")],
        )
        .await?;
    assert_eq!(0, len);

    let len = client
        .geoadd(
            "key",
            None,
            true,
            [(2.0, 2.0, "location1"), (2.0, 2.0, "location2")],
        )
        .await?;
    assert_eq!(1, len);

    let len = client
        .geoadd(
            "key",
            GeoAddCondition::XX,
            true,
            [
                (1.0, 1.0, "location1"),
                (2.0, 2.0, "location2"),
                (3.0, 3.0, "location3"),
            ],
        )
        .await?;
    assert_eq!(1, len);

    let len = client
        .geoadd(
            "key",
            GeoAddCondition::NX,
            true,
            [
                (2.0, 2.0, "location1"),
                (2.0, 2.0, "location2"),
                (3.0, 3.0, "location3"),
            ],
        )
        .await?;
    assert_eq!(1, len);

    Ok(())
}

#[cfg_attr(feature = "tokio-runtime", tokio::test)]
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
#[serial]
async fn geodist() -> Result<()> {
    let client = get_test_client().await?;

    // cleanup
    client.del("Sicily").await?;

    let len = client
        .geoadd(
            "Sicily",
            None,
            false,
            [
                (13.361389, 38.115556, "Palermo"),
                (15.087269, 37.502669, "Catania"),
            ],
        )
        .await?;
    assert_eq!(2, len);

    let dist = client
        .geodist("Sicily", "Palermo", "Catania", GeoUnit::Meters)
        .await?;
    assert_eq!(Some(166274.1516), dist);

    let dist = client
        .geodist("Sicily", "Palermo", "Catania", GeoUnit::Kilometers)
        .await?;
    assert_eq!(Some(166.2742), dist);

    let dist = client
        .geodist("Sicily", "Palermo", "Catania", GeoUnit::Miles)
        .await?;
    assert_eq!(Some(103.3182), dist);

    let dist = client
        .geodist("Sicily", "Foo", "Bar", GeoUnit::Meters)
        .await?;
    assert_eq!(None, dist);

    Ok(())
}

#[cfg_attr(feature = "tokio-runtime", tokio::test)]
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
#[serial]
async fn geohash() -> Result<()> {
    let client = get_test_client().await?;

    // cleanup
    client.del("Sicily").await?;

    let len = client
        .geoadd(
            "Sicily",
            None,
            false,
            [
                (13.361389, 38.115556, "Palermo"),
                (15.087269, 37.502669, "Catania"),
            ],
        )
        .await?;
    assert_eq!(2, len);

    let hashes: Vec<String> = client.geohash("Sicily", ["Palermo", "Catania"]).await?;
    assert_eq!(2, hashes.len());
    assert_eq!("sqc8b49rny0", hashes[0]);
    assert_eq!("sqdtr74hyu0", hashes[1]);

    Ok(())
}

#[cfg_attr(feature = "tokio-runtime", tokio::test)]
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
#[serial]
async fn geopos() -> Result<()> {
    let client = get_test_client().await?;

    // cleanup
    client.del("Sicily").await?;

    let len = client
        .geoadd(
            "Sicily",
            None,
            false,
            [
                (13.361389, 38.115556, "Palermo"),
                (15.087269, 37.502669, "Catania"),
            ],
        )
        .await?;
    assert_eq!(2, len);

    let hashes = client
        .geopos("Sicily", ["Palermo", "Catania", "NonExisting"])
        .await?;
    assert_eq!(3, hashes.len());
    assert_eq!(Some((13.361389338970184, 38.1155563954963)), hashes[0]);
    assert_eq!(Some((15.087267458438873, 37.50266842333162)), hashes[1]);
    assert_eq!(None, hashes[2]);

    Ok(())
}

#[cfg_attr(feature = "tokio-runtime", tokio::test)]
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
#[serial]
async fn geosearch() -> Result<()> {
    let client = get_test_client().await?;

    // cleanup
    client.del("Sicily").await?;

    let len = client
        .geoadd(
            "Sicily",
            None,
            false,
            [
                (13.361389, 38.115556, "Palermo"),
                (15.087269, 37.502669, "Catania"),
            ],
        )
        .await?;
    assert_eq!(2, len);

    let len = client
        .geoadd(
            "Sicily",
            None,
            false,
            [
                (12.758489, 38.788135, "edge1"),
                (17.241510, 38.788135, "edge2"),
            ],
        )
        .await?;
    assert_eq!(2, len);

    let results: Vec<GeoSearchResult<String>> = client
        .geosearch(
            "Sicily",
            GeoSearchFrom::from_longitude_latitude(15.0, 37.0),
            GeoSearchBy::by_radius(200.0, GeoUnit::Kilometers),
            GeoSearchOptions::default(),
        )
        .await?;
    assert_eq!(2, results.len());
    assert!(results.iter().any(|r| r.member == "Palermo",));
    assert!(results.iter().any(|r| r.member == "Catania"));

    let results: Vec<GeoSearchResult<String>> = client
        .geosearch(
            "Sicily",
            GeoSearchFrom::from_longitude_latitude(15.0, 37.0),
            GeoSearchBy::by_box(400.0, 400.0, GeoUnit::Kilometers),
            GeoSearchOptions::default()
                .order(GeoSearchOrder::Asc)
                .with_coord()
                .with_dist(),
        )
        .await?;

    assert_eq!(4, results.len());
    assert_eq!("Catania", results[0].member);
    assert_eq!(Some(56.4413), results[0].distance);
    assert_eq!(None, results[0].geo_hash);
    assert_eq!(
        Some((15.087267458438873, 37.50266842333162)),
        results[0].coordinates
    );
    assert_eq!("Palermo", results[1].member);
    assert_eq!(Some(190.4424), results[1].distance);
    assert_eq!(None, results[1].geo_hash);
    assert_eq!(
        Some((13.361389338970184, 38.1155563954963)),
        results[1].coordinates
    );
    assert_eq!("edge2", results[2].member);
    assert_eq!(Some(279.7403), results[2].distance);
    assert_eq!(None, results[2].geo_hash);
    assert_eq!(
        Some((17.241510450839996, 38.78813451624225)),
        results[2].coordinates
    );
    assert_eq!("edge1", results[3].member);
    assert_eq!(Some(279.7405), results[3].distance);
    assert_eq!(None, results[3].geo_hash);
    assert_eq!(
        Some((12.75848776102066, 38.78813451624225)),
        results[3].coordinates
    );

    Ok(())
}

#[cfg_attr(feature = "tokio-runtime", tokio::test)]
#[cfg_attr(feature = "async-std-runtime", async_std::test)]
#[serial]
async fn geosearchstore() -> Result<()> {
    let client = get_test_client().await?;

    // cleanup
    client.del(["Sicily", "out"]).await?;

    let len = client
        .geoadd(
            "Sicily",
            None,
            false,
            [
                (13.361389, 38.115556, "Palermo"),
                (15.087269, 37.502669, "Catania"),
            ],
        )
        .await?;
    assert_eq!(2, len);

    let len = client
        .geoadd(
            "Sicily",
            None,
            false,
            [
                (12.758489, 38.788135, "edge1"),
                (17.241510, 38.788135, "edge2"),
            ],
        )
        .await?;
    assert_eq!(2, len);

    let len = client
        .geosearchstore(
            "out",
            "Sicily",
            GeoSearchFrom::from_longitude_latitude(15.0, 37.0),
            GeoSearchBy::by_box(400.0, 400.0, GeoUnit::Kilometers),
            GeoSearchStoreOptions::default()
                .order(GeoSearchOrder::Asc)
                .count(3, false),
        )
        .await?;
    assert_eq!(3, len);

    let results: Vec<GeoSearchResult<String>> = client
        .geosearch(
            "out",
            GeoSearchFrom::from_longitude_latitude(15.0, 37.0),
            GeoSearchBy::by_box(400.0, 400.0, GeoUnit::Kilometers),
            GeoSearchOptions::default()
                .order(GeoSearchOrder::Asc)
                .with_coord()
                .with_dist()
                .with_hash(),
        )
        .await?;

    assert_eq!(3, results.len());
    assert_eq!("Catania", results[0].member);
    assert_eq!(Some(56.4413), results[0].distance);
    assert_eq!(Some(3479447370796909), results[0].geo_hash);
    assert_eq!(
        Some((15.087267458438873, 37.50266842333162)),
        results[0].coordinates
    );
    assert_eq!("Palermo", results[1].member);
    assert_eq!(Some(190.4424), results[1].distance);
    assert_eq!(Some(3479099956230698), results[1].geo_hash);
    assert_eq!(
        Some((13.361389338970184, 38.1155563954963)),
        results[1].coordinates
    );
    assert_eq!("edge2", results[2].member);
    assert_eq!(Some(279.7403), results[2].distance);
    assert_eq!(Some(3481342659049484), results[2].geo_hash);
    assert_eq!(
        Some((17.241510450839996, 38.78813451624225)),
        results[2].coordinates
    );

    Ok(())
}