1
1
use bonsaidb::{
2
    core::{
3
        connection::Connection,
4
        document::{BorrowedDocument, Emit},
5
        key::EnumKey,
6
        schema::{
7
            view::map::ViewMappedValue, Collection, ReduceResult, SerializedCollection, View,
8
            ViewMapResult, ViewSchema,
9
        },
10
        Error,
11
    },
12
    local::{
13
        config::{Builder, StorageConfiguration},
14
        Database,
15
    },
16
};
17
use serde::{Deserialize, Serialize};
18

            
19
// ANCHOR: enum
20
#[derive(
21
4
    Serialize, Deserialize, Debug, num_derive::FromPrimitive, num_derive::ToPrimitive, Clone,
22
)]
23
pub enum Category {
24
    Rust,
25
    Cooking,
26
}
27

            
28
impl EnumKey for Category {}
29
// ANCHOR_END: enum
30

            
31
// ANCHOR: struct
32
2
#[derive(Serialize, Deserialize, Debug, Collection)]
33
#[collection(name = "blog-post", views = [BlogPostsByCategory])]
34
pub struct BlogPost {
35
    pub title: String,
36
    pub body: String,
37
    pub category: Option<Category>,
38
}
39
// ANCHOR_END: struct
40

            
41
// ANCHOR: view
42

            
43
13
#[derive(Debug, Clone, View)]
44
#[view(collection = BlogPost, key = Option<Category>, value = u32, name = "by-category")]
45
pub struct BlogPostsByCategory;
46

            
47
impl ViewSchema for BlogPostsByCategory {
48
    type View = Self;
49

            
50
    fn map(&self, document: &BorrowedDocument<'_>) -> ViewMapResult<Self::View> {
51
        let post = BlogPost::document_contents(document)?;
52
        document.header.emit_key_and_value(post.category, 1)
53
    }
54

            
55
2
    fn reduce(
56
2
        &self,
57
2
        mappings: &[ViewMappedValue<Self::View>],
58
2
        _rereduce: bool,
59
2
    ) -> ReduceResult<Self::View> {
60
2
        Ok(mappings.iter().map(|mapping| mapping.value).sum())
61
2
    }
62
}
63
// ANCHOR_END: view
64

            
65
#[allow(unused_variables)]
66
1
#[tokio::test]
67
1
async fn example() -> Result<(), Error> {
68
1
    drop(tokio::fs::remove_dir_all("example.bonsaidb").await);
69
19
    let db = Database::open::<BlogPost>(StorageConfiguration::new("example.bonsaidb")).await?;
70
    // ANCHOR: query_with_docs
71
1
    let rust_posts = db
72
1
        .view::<BlogPostsByCategory>()
73
1
        .with_key(Some(Category::Rust))
74
2
        .query_with_docs()
75
2
        .await?;
76
    // ANCHOR_END: query_with_docs
77
    // ANCHOR: reduce_one_key
78
1
    let rust_post_count = db
79
1
        .view::<BlogPostsByCategory>()
80
1
        .with_key(Some(Category::Rust))
81
1
        .reduce()
82
        .await?;
83
    // ANCHOR_END: reduce_one_key
84
    // ANCHOR: reduce_multiple_keys
85
1
    let total_post_count = db.view::<BlogPostsByCategory>().reduce().await?;
86
    // ANCHOR_END: reduce_multiple_keys
87
1
    Ok(())
88
1
}