1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
/// Construct a `serde_json::Value` from a JSON literal
/// representing document.
///
/// This is equivalent to serde_json::json but also adds
/// _id field with uuid
///
/// ```
/// # #[cfg(not(feature = "sync"))]
/// use memquery::{doc, errors::Error, memdb::MemDb};
///
/// # #[cfg(not(feature = "sync"))]
/// async fn play() -> Result<(), Error> {
///   let memdb = MemDb::new();
///   let coll = memdb.collection("TestCollection").await?;
///
///   coll.insert(doc!({ "name": "Tom", "age": 25 })).await?;
///   Ok(())
/// }
/// ```
#[macro_export]
macro_rules! doc {
  ($($json:tt)+) => {
    {
    let mut v = serde_json::json!($($json)+);
    assert!(v.is_object());
    v["_id"] = serde_json::json!(uuid::Uuid::new_v4());
    v
    }
  };
}

/// Construct a `serde_json::Value` from a JSON literal
/// representing query spec.
///
///
/// ```
/// # #[cfg(not(feature = "sync"))]
/// use memquery::{doc, errors::Error, memdb::MemDb, query};
///
/// # #[cfg(not(feature = "sync"))]
/// async fn play() -> Result<(), Error> {
///   let memdb = MemDb::new();
///   let coll = memdb.collection("TestCollection").await?;
///
///   coll.insert(doc!({ "name": "Tom", "age": 25 })).await?;
///   let docs = coll.find(query!({"name": "Tom", "age": 25})).await?;
///   Ok(())
/// }
/// ```
#[macro_export]
macro_rules! query {
  ($($json:tt)+) => {
    serde_json::json!($($json)+)
  };
}

/// Construct a `serde_json::Value` from a JSON literal
/// representing update value for find_and_update API.
///
///
/// ```
/// # #[cfg(not(feature = "sync"))]
/// use memquery::{doc, errors::Error, memdb::MemDb, query, update};
///
/// # #[cfg(not(feature = "sync"))]
/// async fn play() -> Result<(), Error> {
///   let memdb = MemDb::new();
///   let coll = memdb.collection("TestCollection").await?;
///
///   coll.insert(doc!({ "name": "Tom", "age": 25 })).await?;
///   let docs_updated = coll
///     .find_and_update(
///     query!({ "name": "Tom" }),
///     update!({ "$set": { "name": "Roy", "age": 21, "email": "test@test.com" }}),
///   )
///   .await?;
///   Ok(())
/// }
/// ```
#[macro_export]
macro_rules! update {
  ($($json:tt)+) => {
    serde_json::json!($($json)+)
  };
}

#[cfg(test)]
mod tests {
  #[test]
  fn test_adding_id() {
    let doc = doc!({ "name": "test", "value": 1 });
    assert_ne!(doc["_id"], serde_json::Value::Null);
    println!("doc {}", doc);
  }

  #[test]
  #[should_panic]
  fn reject_non_object() {
    doc!(1);
  }
}