ledger-core
Try.hpp
1 /*
2  *
3  * Try
4  * ledger-core
5  *
6  * Created by Pierre Pollastri on 13/12/2016.
7  *
8  * The MIT License (MIT)
9  *
10  * Copyright (c) 2016 Ledger
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy
13  * of this software and associated documentation files (the "Software"), to deal
14  * in the Software without restriction, including without limitation the rights
15  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16  * copies of the Software, and to permit persons to whom the Software is
17  * furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included in all
20  * copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28  * SOFTWARE.
29  *
30  */
31 #ifndef LEDGER_CORE_TRY_HPP
32 #define LEDGER_CORE_TRY_HPP
33 
34 #ifdef TARGET_JNI
35 #include <jni/jni/djinni_support.hpp>
36 #endif
37 
38 #include <functional>
39 #include "optional.hpp"
40 #include "Option.hpp"
41 #include "Exception.hpp"
42 #include <typeinfo>
43 #include <stdexcept>
44 #include <boost/exception/diagnostic_information.hpp>
45 
46 namespace ledger {
47  namespace core {
48  template <typename T>
49  class Try {
50  public:
51  Try() {
52 
53  };
54 
55  Try(const T&v) {
56  _value = optional<T>(v);
57  }
58 
59  Try(api::ErrorCode code, const std::string& message) {
60  fail(code, message);
61  }
62 
63  void fail(api::ErrorCode code, const std::string& message) {
64  _exception = Exception(code, message);
65  }
66 
67  void fail(const Exception& ex) {
68  _exception = ex;
69  }
70 
71  void success(const T& v) {
72  _value = v;
73  }
74 
75  const T& getValue() const {
76  return _value.value();
77  }
78 
79  const Exception& getFailure() const {
80  return _exception.value();
81  }
82 
83  bool isFailure() const {
84  return _exception ? true : false;
85  }
86  bool isSuccess() const {
87  return _value ? true : false;
88  }
89  bool isComplete() const {
90  return isSuccess() || isFailure();
91  }
92 
93  Option<T> toOption() const {
94  if (isSuccess())
95  return Option<T>(getValue());
96  return Option<T>();
97  }
98 
99  Option<Exception> exception() const {
100  if (isFailure())
101  return Option<Exception>(getFailure());
102  return Option<Exception>();
103  }
104 
105  const T& getOrThrow() const {
106  if (isFailure())
107  throw getFailure();
108  return getValue();
109  }
110 
111  template <class U>
112  const T& getOrThrowException() const {
113  if (isFailure())
114  throw U(getFailure().getMessage());
115  return getValue();
116  }
117 
118  Try<T> mapException(api::ErrorCode code) {
119  if (isFailure())
120  return Try<T>(code, getFailure().getMessage());
121  return *this;
122  }
123 
124 // friend std::ostream &operator<<(std::ostream &os, const Try<T> &d) {
125 // if (d.isSuccess()) {
126 // os << "Success(" << d.getFailure() << ")";
127 // } else {
128 // os << "Failure(" << d.getFailure() << ")";
129 // }
130 // }
131 
132  ~Try() {
133 
134  };
135  private:
136  optional<Exception> _exception;
137  optional<T> _value;
138 
139  public:
140  static const Try<T> from(std::function<T ()> lambda) {
141  Try<T> result;
142  try {
143  result.success(lambda());
144  } catch (const Exception& ex) {
145  result.fail(ex);
146 #ifdef TARGET_JNI
147  } catch (const djinni::jni_exception& ex) {
148  result.fail(api::ErrorCode::RUNTIME_ERROR, ex.get_backtrace());
149 #endif
150  } catch (...) {
151  result.fail(api::ErrorCode::RUNTIME_ERROR, boost::current_exception_diagnostic_information(true));
152  }
153  return result;
154  }
155  };
156 
157  template <typename T>
159 
160  template<typename T>
161  Try<T> make_try(std::function<T ()> lambda) {
162  return Try<T>::from(lambda);
163  }
164  }
165 }
166 
167 
168 #endif //LEDGER_CORE_TRY_HPP
Definition: Try.hpp:49
Definition: Option.hpp:49
Definition: djinni_support.hpp:112
Definition: Account.cpp:8
ErrorCode
Definition: ErrorCode.hpp:20
Definition: optional.hpp:177
Definition: Exception.hpp:45