Skip to content

Commit 5e923e1

Browse files
authored
Release/0.7.0
2 parents 1ac01d9 + f1a2cdb commit 5e923e1

30 files changed

+902
-683
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: scala
2+
dist: trusty
23
scala:
3-
- 2.11.12
4-
- 2.12.7
4+
- 2.12.8
55
jdk:
66
- oraclejdk8
77
env:
@@ -18,7 +18,7 @@ deploy:
1818
provider: script
1919
script: ./.travis/deploy.sh $TRAVIS_TAG
2020
on:
21-
condition: '"${TRAVIS_SCALA_VERSION}" == "2.11.12" && "${TRAVIS_JDK_VERSION}" == "oraclejdk8"'
21+
condition: '"${TRAVIS_SCALA_VERSION}" == "2.12.8" && "${TRAVIS_JDK_VERSION}" == "oraclejdk8"'
2222
tags: true
2323
after_success:
2424
- bash <(curl -s https://codecov.io/bash)

CHANGELOG

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
Version 0.7.0 (2019-11-11)
2+
--------------------------
3+
Introduce tagless final encoding (#158)
4+
Abstract over Forex creation (#161)
5+
Support cats.Id (#163)
6+
Introduce scalaj (#162)
7+
Remove infinite recursion when converting currencies (#166)
8+
Turn objects into case objects (#167)
9+
Skip tests if the API key is absent (#148)
10+
Add readme examples (#164)
11+
Bump Scala to 2.12.8 (#149)
12+
Bump joda-convert to 2.2.0 (#150)
13+
Bump cats-effect to 1.2.0 (#151)
14+
Bump circe to 0.11.1 (#152)
15+
Bump scala-lru-map to 0.3.0 (#154)
16+
Bump specs2 to 4.4.1 (#153)
17+
Bump SBT to 1.2.8 (#159)
18+
Use sbt-tpolecat (#147)
19+
Remove Scala 2.11 (#157)
20+
Change Travis distribution to Trusty (#168)
21+
Extend copyright to 2019 (#160)
22+
123
Version 0.6.0 (2018-10-03)
224
--------------------------
325
Add code coverage reports (#144)

LICENSE-2.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ recommend that a file or class name and description of purpose be included on
176176
the same "printed page" as the copyright notice for easier identification within
177177
third-party archives.
178178

179-
Copyright [yyyy] [name of copyright owner]
179+
Copyright 2012-2019 Snowplow Analytics Ltd.
180180

181181
Licensed under the Apache License, Version 2.0 (the "License");
182182
you may not use this file except in compliance with the License.

README.md

Lines changed: 61 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,31 @@ There are three types of accounts supported by OER API, Unlimited, Enterprise an
2424

2525
### 2.2 Installation
2626

27-
The latest version of Scala Forex is 0.6.0, which is cross-built against 2.11.x and 2.12.x.
27+
The latest version of Scala Forex is 0.7.0, which is built against 2.12.x.
2828

2929
If you're using SBT, add the following lines to your build file:
3030

3131
```scala
3232
libraryDependencies ++= Seq(
33-
"com.snowplowanalytics" %% "scala-forex" % "0.6.0"
33+
"com.snowplowanalytics" %% "scala-forex" % "0.7.0"
3434
)
3535
```
3636

3737
Note the double percent (`%%`) between the group and artifactId. That'll ensure you get the right package for your Scala version.
3838

3939
## 3. Usage
4040

41-
The Scala Forex supports two types of usage:
41+
The Scala Forex library supports two types of usage:
4242

4343
1. Exchange rate lookups
4444
2. Currency conversions
4545

4646
Both usage types support live, near-live or historical (end-of-day) exchange rates.
4747

4848
For all code samples below we are assuming the following imports:
49+
4950
```scala
5051
import org.joda.money.CurrencyUnit
51-
import cats.effect.IO
5252
import com.snowplowanalytics.forex._
5353
```
5454

@@ -75,13 +75,13 @@ To go through each in turn:
7575

7676
2. `accountLevel` is the type of OER account you have. Possible values are `UnlimitedAccount`, `EnterpriseAccount`, and `DeveloperAccount`.
7777

78-
1. `nowishCacheSize` is the size configuration for near-live(nowish) lookup cache, it can be disabled by setting its value to 0. The key to nowish cache is a currency pair so the size of the cache equals to the number of pairs of currencies available.
78+
1. `nowishCacheSize` is the size configuration for near-live (nowish) lookup cache, it can be disabled by setting its value to 0. The key to nowish cache is a currency pair so the size of the cache equals to the number of pairs of currencies available.
7979

80-
2. `nowishSecs` is the time configuration for near-live lookup. Nowish call will use the exchange rates stored in nowish cache if its time stamp is less than or equal to `nowishSecs` old.
80+
2. `nowishSecs` is the time configuration for near-live lookup. A call to this cache will use the exchange rates stored in nowish cache if its time stamp is less than or equal to `nowishSecs` old.
8181

82-
3. `eodCacheSize` is the size configuration for end-of-day(eod) lookup cache, it can be disabled by setting its value to 0. The key to eod cache is a tuple of currency pair and time stamp, so the size of eod cache equals to the number of currency pairs times the days which the cache will remember the data for.
82+
3. `eodCacheSize` is the size configuration for end-of-day (eod) lookup cache, it can be disabled by setting its value to 0. The key to eod cache is a tuple of currency pair and time stamp, so the size of eod cache equals to the number of currency pairs times the days which the cache will remember the data for.
8383

84-
4. `getNearestDay` is the rounding configuration for latest eod(at) lookup. The lookup will be performed on the next day if the rounding mode is set to EodRoundUp, and on the previous day if EodRoundDown.
84+
4. `getNearestDay` is the rounding configuration for latest eod (at) lookup. The lookup will be performed on the next day if the rounding mode is set to EodRoundUp, and on the previous day if EodRoundDown.
8585

8686
5. `baseCurrency` can be configured to different currencies by the users.
8787

@@ -90,70 +90,91 @@ For an explanation for the default values please see section **5.4 Explanation o
9090
### 3.2 Rate lookup
9191

9292
Unless specified otherwise, assume `forex` value is initialized as:
93+
9394
```scala
9495
val config: ForexConfig = ForexConfig("YOUR_API_KEY", DeveloperAccount)
95-
val forex: IO[Forex] = Forex.getForex[IO](config)
96+
def fForex[F[_]: Sync]: F[Forex] = CreateForex[F].create(config)
9697
```
9798

98-
`Forex.getForex[IO]` returns `IO[Forex]` instead of `Forex`, because creation of the underlying caches is
99-
a side effect. You can `flatMap` over the result (or use a for-comprehension, as seen below).
100-
All examples below return `IO[Either[OerResponseError], Money]`, which means they are not executed.
101-
You will need to run `unsafeRunSync` on them to retrieve the result.
99+
`CreateForex[F].create` returns `F[Forex]` instead of `Forex`, because creation of the underlying
100+
caches is a side effect. You can `flatMap` over the result (or use a for-comprehension, as seen
101+
below). All examples below return `F[Either[OerResponseError, Money]]`, which means they are not
102+
executed.
103+
104+
If you don't care about side effects, we also provide instance of `Forex` for `cats.Eval` and
105+
`cats.Id`:
106+
107+
```scala
108+
val evalForex: Eval[Forex] = CreateForex[Eval].create(config)
109+
val idForex: Forex = CreateForex[Id].create(config)
110+
```
111+
112+
For distributed applications, such as Spark or Beam apps, where lazy values might be an issue, you may want to use the `Id` instance.
102113

103114
#### 3.2.1 Live rate
104115

105-
Lookup a live rate _(no caching available)_:
116+
Look up a live rate _(no caching available)_:
106117

107118
```scala
108119
// USD => JPY
109-
val usd2jpy = for {
110-
fx <- forex
120+
val usd2jpyF: F[Either[OerResponseError, Money]] = for {
121+
fx <- fForex
111122
result <- fx.rate.to(CurrencyUnit.JPY).now
112123
} yield result
124+
125+
// using Eval
126+
val usd2jpyE: Eval[Either[OerResponseError, Money]] = for {
127+
fx <- evalForex
128+
result <- fx.rate.to(CurrencyUnit.JPY).now
129+
} yield result
130+
131+
// using Id
132+
val usd2jpyI: Either[OerResponseError, Money] =
133+
idForex.rate.to(CurrencyUnit.JPY).now
113134
```
114135

115136
#### 3.2.2 Near-live rate
116137

117-
Lookup a near-live rate _(caching available)_:
138+
Look up a near-live rate _(caching available)_:
118139

119140
```scala
120141
// JPY => GBP
121142
val jpy2gbp = for {
122-
fx <- forex
143+
fx <- fForex
123144
result <- fx.rate(CurrencyUnit.JPY).to(CurrencyUnit.GBP).nowish
124145
} yield result
125146
```
126147

127148
#### 3.2.3 Near-live rate without cache
128149

129-
Lookup a near-live rate (_uses cache selectively_):
150+
Look up a near-live rate (_uses cache selectively_):
130151

131152
```scala
132153
// JPY => GBP
133154
val jpy2gbp = for {
134-
fx <- Forex.getForex[IO](ForexConfig("YOU_API_KEY", DeveloperAccount, nowishCacheSize = 0))
155+
fx <- CreateForex[IO].create(ForexConfig("YOU_API_KEY", DeveloperAccount, nowishCacheSize = 0))
135156
result <- fx.rate(CurrencyUnit.JPY).to(CurrencyUnit.GBP).nowish
136157
} yield result
137158
```
138159

139160
#### 3.2.4 Latest-prior EOD rate
140161

141-
Lookup the latest EOD (end-of-date) rate prior to your event _(caching available)_:
162+
Look up the latest EOD (end-of-date) rate prior to your event _(caching available)_:
142163

143164
```scala
144165
import java.time.{ZonedDateTime, ZoneId}
145166

146167
// USD => JPY at the end of 13/03/2011
147168
val tradeDate = ZonedDateTime.of(2011, 3, 13, 11, 39, 27, 567, ZoneId.of("America/New_York"))
148169
val usd2jpy = for {
149-
fx <- forex
170+
fx <- fForex
150171
result <- fx.rate.to(CurrencyUnit.JPY).at(tradeDate)
151172
} yield result
152173
```
153174

154175
#### 3.2.5 Latest-post EOD rate
155176

156-
Lookup the latest EOD (end-of-date) rate post to your event _(caching available)_:
177+
Look up the latest EOD (end-of-date) rate post to your event _(caching available)_:
157178

158179
```scala
159180
// USD => JPY at the end of 13/03/2011
@@ -166,7 +187,7 @@ val usd2jpy = for {
166187

167188
#### 3.2.6 Specific EOD rate
168189

169-
Lookup the EOD rate for a specific date _(caching available)_:
190+
Look up the EOD rate for a specific date _(caching available)_:
170191

171192
```scala
172193
// GBP => JPY at the end of 13/03/2011
@@ -179,7 +200,7 @@ val gbp2jpy = for {
179200

180201
#### 3.2.7 Specific EOD rate without cache
181202

182-
Lookup the EOD rate for a specific date _(no caching)_:
203+
Look up the EOD rate for a specific date _(no caching)_:
183204

184205
```scala
185206
// GBP => JPY at the end of 13/03/2011
@@ -207,26 +228,26 @@ val priceInEuros = for {
207228

208229
#### 3.3.2 Near-live rate
209230

210-
Conversion using a near-live exchange rate with 500 seconds nowishSecs _(caching available)_:
231+
Conversion using a near-live exchange rate with 500 seconds `nowishSecs` _(caching available)_:
211232

212233
```scala
213234
// 9.99 GBP => EUR
214235
val priceInEuros = for {
215-
fx <- Forex.getForex[IO](ForexConfig("YOU_API_KEY", DeveloperAccount, nowishSecs = 500))
236+
fx <- CreateForex[IO].create(ForexConfig("YOU_API_KEY", DeveloperAccount, nowishSecs = 500))
216237
result <- fx.convert(9.99, CurrencyUnit.GBP).to(CurrencyUnit.EUR).nowish
217238
} yield result
218239
```
219240

220241
#### 3.3.3 Near-live rate without cache
221242

222243
Note that this will be a live rate conversion if cache is not available.
223-
Conversion using a live exchange rate with 500 seconds nowishSecs,
244+
Conversion using a live exchange rate with 500 seconds `nowishSecs`,
224245
this conversion will be done via HTTP request:
225246

226247
```scala
227248
// 9.99 GBP => EUR
228249
val priceInEuros = for {
229-
fx <- Forex.getForex[IO](ForexConfig("YOUR_API_KEY", DeveloperAccount, nowishSecs = 500, nowishCacheSize = 0))
250+
fx <- CreateForex[IO].create(ForexConfig("YOUR_API_KEY", DeveloperAccount, nowishSecs = 500, nowishCacheSize = 0))
230251
result <- fx.convert(9.99, CurrencyUnit.GBP).to(CurrencyUnit.EUR).nowish
231252
} yield result
232253
```
@@ -252,7 +273,7 @@ Lookup the latest EOD (end-of-date) rate following your event _(caching availabl
252273
// 10000 GBP => JPY at the end of 13/03/2011
253274
val tradeDate = ZonedDateTime.of(2011, 3, 13, 11, 39, 27, 567, ZoneId.of("America/New_York"))
254275
val usd2jpy = for {
255-
fx <- Forex.getForex[IO](ForexConfig("Your API key / app id", DeveloperAccount, getNearestDay = EodRoundUp))
276+
fx <- CreateForex[IO].create(ForexConfig("Your API key / app id", DeveloperAccount, getNearestDay = EodRoundUp))
256277
result <- fx.convert(10000, CurrencyUnit.GBP).to(CurrencyUnit.JPY).at(tradeDate)
257278
} yield result
258279
```
@@ -289,7 +310,7 @@ val tradeInYen = for {
289310
#### 3.4.1 LRU cache
290311

291312
The `eodCacheSize` and `nowishCacheSize` values determine the maximum number of values to keep in the LRU cache,
292-
which the Client will check prior to making an API lookup. To disable eithe LRU cache, set its size to zero,
313+
which the Client will check prior to making an API lookup. To disable either LRU cache, set its size to zero,
293314
i.e. `eodCacheSize = 0`.
294315

295316
#### 3.4.2 From currency selection
@@ -301,7 +322,7 @@ If not specified, `baseCurrency` is set to USD by default.
301322

302323
### 4.1 Running tests
303324

304-
You **must** export your `OER_KEY` or else the test suite will fail. To run the test suite locally:
325+
You **must** export your `OER_KEY` or else the tests will be skipped. To run the test suite locally:
305326

306327
```
307328
$ export OER_KEY=<<key>>
@@ -360,9 +381,13 @@ We selected USD for the base currency because this is the OER default as well.
360381

361382
With Open Exchange Rates' Unlimited and Enterprise accounts, Scala Forex can specify the base currency to use when looking up exchange rates; Developer-level accounts will always retrieve rates against USD, so a rate lookup from e.g. GBY to EUR will require two conversions (GBY -> USD -> EUR). For this reason, we recommend Unlimited and Enterprise-level accounts for slightly more accurate non-USD-related lookups.
362383

363-
## 6. Copyright and license
384+
## 6. Documentation
385+
386+
The Scaladoc pages for this library can be found [here][scaladoc-pages].
364387

365-
Scala Forex is copyright 2013-2018 Snowplow Analytics Ltd.
388+
## 7. Copyright and license
389+
390+
Scala Forex is copyright 2013-2019 Snowplow Analytics Ltd.
366391

367392
Licensed under the [Apache License, Version 2.0][license] (the "License");
368393
you may not use this software except in compliance with the License.
@@ -388,3 +413,5 @@ limitations under the License.
388413

389414
[gitter-image]: https://badges.gitter.im/snowplow/scala-forex.svg
390415
[gitter-link]: https://gitter.im/snowplow/scala-forex?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
416+
417+
[scaladoc-pages]: http://snowplow.github.io/scala-forex/

build.sbt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013-2018 Snowplow Analytics Ltd. All rights reserved.
2+
* Copyright (c) 2013-2019 Snowplow Analytics Ltd. All rights reserved.
33
*
44
* This program is licensed to you under the Apache License Version 2.0,
55
* and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -17,7 +17,7 @@ lazy val root = project.in(file("."))
1717
.enablePlugins(ScalaUnidocPlugin, GhpagesPlugin)
1818
.settings(
1919
name := "scala-forex",
20-
version := "0.6.0",
20+
version := "0.7.0",
2121
description := "High-performance Scala library for performing currency conversions using Open Exchange Rates"
2222
)
2323
.settings(BuildSettings.buildSettings)
@@ -31,6 +31,7 @@ lazy val root = project.in(file("."))
3131
Dependencies.Libraries.catsEffect,
3232
Dependencies.Libraries.circeParser,
3333
Dependencies.Libraries.lruMap,
34+
Dependencies.Libraries.scalaj,
3435
Dependencies.Libraries.specs2Core,
3536
Dependencies.Libraries.specs2Mock
3637
)

project/BuildSettings.scala

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013-2018 Snowplow Analytics Ltd. All rights reserved.
2+
* Copyright (c) 2013-2019 Snowplow Analytics Ltd. All rights reserved.
33
*
44
* This program is licensed to you under the Apache License Version 2.0,
55
* and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -32,29 +32,7 @@ object BuildSettings {
3232
// Basic settings for our app
3333
lazy val buildSettings = Seq[Setting[_]](
3434
organization := "com.snowplowanalytics",
35-
scalaVersion := "2.12.7",
36-
crossScalaVersions := Seq("2.11.12", "2.12.7"),
37-
scalacOptions := compilerOptions,
38-
39-
addCompilerPlugin(
40-
"org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full
41-
)
42-
)
43-
44-
lazy val compilerOptions = Seq(
45-
"-deprecation",
46-
"-encoding", "UTF-8",
47-
"-feature",
48-
"-language:existentials",
49-
"-language:higherKinds",
50-
"-language:implicitConversions",
51-
"-unchecked",
52-
"-Yno-adapted-args",
53-
"-Ywarn-dead-code",
54-
"-Ywarn-numeric-widen",
55-
"-Ypartial-unification",
56-
"-Xfuture",
57-
"-Xlint"
35+
scalaVersion := "2.12.8",
5836
)
5937

6038
// Publish settings

0 commit comments

Comments
 (0)