summaryrefslogtreecommitdiffstats
path: root/sandbox/sebastien/cpp/apr-2/samples/store-cpp/shopping-cart.cpp
blob: 738ab2f4c7f377cd6106bc94d5c8a08f3e2667b4 (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* $Rev$ $Date$ */

/**
 * Shopping cart component implementation.
 */

#include "string.hpp"
#include "function.hpp"
#include "list.hpp"
#include "value.hpp"
#include "monad.hpp"

namespace tuscany {
namespace store {

const string cartId("1234");

/**
 * Get the shopping cart from the cache. Return an empty
 * cart if not found.
 */
const list<value> getcart(const value& id, const lambda<value(const list<value>&)> cache) {
    const value cart = cache(mklist<value>("get", mklist<value>(id)));
    cerr << "cart value: " << cart << "\n";
    const failable<value> fcart = cart;
    cerr << "cart fvalue: " << fcart << "\n";
    cerr << "cart content: " << content(fcart) << "\n";
    cerr << "cart reason: " << reason(fcart) << "\n";
    if (isNil(cart))
        return value(list<value>());
    return (list<value>)cart;
}

/**
 * Post a new item to the cart. Create a new cart if necessary.
 */
const failable<value> post(unused const list<value>& collection, const value& item, const lambda<value(const list<value>&)> cache) {
    const value id(mkuuid());
    const list<value> newItem(mklist<value>(car<value>(item), id, caddr<value>(item)));
    const list<value> cart(cons<value>(newItem, getcart(cartId, cache)));
    cache(mklist<value>("put", mklist<value>(cartId), cart));
    return value(mklist<value>(id));
}

/**
 * Find an item in the cart.
 */
const value find(const value& id, const list<value>& cart) {
    if (isNil(cart))
        return cons<value>(string("Item"), mklist<value>("0", list<value>()));
    if (id == cadr<value>(car(cart)))
        return car(cart);
    return find(id, cdr(cart));
}

/**
 * Return items from the cart.
 */
const failable<value> get(const list<value>& id, const lambda<value(const list<value>&)> cache) {
    if (isNil(id))
        return value(append(mklist<value>(string("Your Cart"), cartId), getcart(cartId, cache)));
    return find(car(id), getcart(cartId, cache));
}

/**
 * Delete items from the cart.
 */
const failable<value> del(const list<value>& id, unused const lambda<value(const list<value>&)> cache) {
    if (isNil(id))
        return cache(mklist<value>("delete", mklist<value>(cartId)));
    return value(true);
}

/**
 * Return the price of an item.
 */
const double price(const list<value>& item) {
    return cadr<value>(assoc<value>("price", caddr(item)));
}

/**
 * Sum the prices of a list of items.
 */
const double sum(const list<value>& items) {
    if (isNil(items))
        return 0;
    return price(car(items)) + sum(cdr(items));
}

/**
 * Return the total price of the items in the cart.
 */
const failable<value> total(const lambda<value(const list<value>&)> cache) {
    const list<value> cart(getcart(cartId, cache));
    return value(sum(cart));
}

}
}

extern "C" {

const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
    const tuscany::value func(car(params));
    if (func == "post")
        return tuscany::store::post(cadr(params), caddr(params), cadddr(params));
    if (func == "get")
        return tuscany::store::get(cadr(params), caddr(params));
    if (func == "delete")
        return tuscany::store::del(cadr(params), caddr(params));
    if (func == "total")
        return tuscany::store::total(cadr(params));
    return tuscany::mkfailure<tuscany::value>();
}

}