squake 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7860b4b9cfbf3110355582ab95ce9faee0055fc6ea852b00093703fbcf8f7c8d
4
- data.tar.gz: 6f05154a58469f7f52f9730bf808a3005961b7ba29e7f6ce8fe47e47b27cc651
3
+ metadata.gz: b36b98d0bbe6be1cfa67c8b2ba81905f7bcdcc929308332b886548bbcd189b56
4
+ data.tar.gz: ee666e2bbd9f7535c824063dd20d5cb9ca90c72e384ff1ed8983bd7400f81d20
5
5
  SHA512:
6
- metadata.gz: d2065bbbe6bbbffa5067acf0810dbfe2c3ef32b50b5bce14b949f170a138f29ec16d2897093d9305af615e768ebcaa6da24873660572c24141e09f11b896cf08
7
- data.tar.gz: 53f6a57201c32df605f6d30932baa4408bc3eafd7c02fb6f2dff6f55d0313c1e0b0f501980aa93e17bcea5ecd3bc11491f81639d138aa4c60005e62237689e92
6
+ metadata.gz: d53fd77ab97f24cc6c3102500863865b7e0852d936b45862bfab7c946d301601b34fc0048135601518b645373ab8e67af1495e0acd039447c703c7284f239d84
7
+ data.tar.gz: 7869d17821522db8690f8c9a1fd0ad950cd8471e7176c3b20f9993b4ad4f01cfb9c6f3d8f1270fb30f77f5bc91f9c5bacb55873d857e60695575c82125100a6a
data/README.md CHANGED
@@ -34,7 +34,7 @@ You need a different API Key for production and sandbox.
34
34
 
35
35
  ## Usage
36
36
 
37
- Calculate emissions and include a price quote:
37
+ Initialize the client:
38
38
 
39
39
  ```ruby
40
40
  config = Squake::Config.new(
@@ -48,7 +48,36 @@ config = Squake::Config.new(
48
48
  # the SQUAKE client emits canonical log lines, e.g.
49
49
  # Request started http_method=get http_path=/api/v2/calculations
50
50
  client = Squake::Client.new(config: config)
51
+ ```
52
+
53
+ Calculate emissions
54
+
55
+ ```ruby
56
+ items = [
57
+ {
58
+ type: 'flight',
59
+ methodology: 'ICAO',
60
+ origin: 'BER',
61
+ destination: 'SIN',
62
+ booking_class: 'economy',
63
+ number_of_travellers: 2,
64
+ aircraft_type: '350',
65
+ external_reference: 'booking-id',
66
+ }
67
+ ]
51
68
 
69
+ # returns Squake::Model::Carbon
70
+ carbon = Squake::Calculation.create(
71
+ client: client, # required
72
+ items: items, # required
73
+ carbon_unit: 'gram', # optional, default: 'gram', other options: 'kilogram', 'tonne'
74
+ expand: [], # optional, default: [], allowed values: 'items' to enrich the response
75
+ )
76
+ ```
77
+
78
+ Calculate emissions and include a price quote:
79
+
80
+ ```ruby
52
81
  # Find all available item types and methodologies here:
53
82
  # https://docs-v2.squake.earth/group/endpoint-calculations
54
83
  items = [
@@ -71,6 +100,7 @@ pricing = Squake::CalculationWithPricing.quote(
71
100
  product: 'product-id', # required
72
101
  currency: 'EUR', # optional, default: 'EUR'
73
102
  carbon_unit: 'gram', # optional, default: 'gram', other options: 'kilogram', 'tonne'
103
+ expand: [], # optional, default: [], allowed values: 'items', 'product', 'price' to enrich the response
74
104
  )
75
105
  ```
76
106
 
@@ -98,3 +128,19 @@ Squake::Purchase.cancel(
98
128
  id: purchase.id, # required
99
129
  )
100
130
  ```
131
+
132
+ ## Publishing a new version
133
+
134
+ Have a Rubygems API key in your `~/.gem/credentials` file.
135
+
136
+ ```shell
137
+ ---
138
+ :rubygems_squake: rubygems_xxx
139
+ ```
140
+
141
+ Then run:
142
+
143
+ ```shell
144
+ gem build
145
+ gem push squake-0.1.0.gem --key=rubygems_squake
146
+ ```
@@ -0,0 +1,36 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ # https://docs-v2.squake.earth/operation/operation-post-calculations
5
+ module Squake
6
+ class Calculation
7
+ extend T::Sig
8
+
9
+ ENDPOINT = T.let('/v2/calculations', String)
10
+
11
+ sig do
12
+ params(
13
+ client: Squake::Client,
14
+ items: T::Array[Squake::Model::Items::BaseType],
15
+ carbon_unit: String,
16
+ expand: T::Array[String],
17
+ ).returns(Squake::Model::Carbon)
18
+ end
19
+ def self.create(client:, items:, carbon_unit: 'gram', expand: [])
20
+ result = client.call(
21
+ path: ENDPOINT,
22
+ method: :post,
23
+ params: {
24
+ items: items.map(&:serialize),
25
+ carbon_unit: carbon_unit,
26
+ expand: expand,
27
+ },
28
+ )
29
+ raise Squake::APIError.new(response: result) unless result.success?
30
+
31
+ Squake::Model::Carbon.from_api_response(
32
+ T.cast(result.body, T::Hash[Symbol, T.untyped]),
33
+ )
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,53 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Squake
5
+ module Model
6
+ class Carbon < T::Struct
7
+ extend T::Sig
8
+
9
+ const :quantity, BigDecimal
10
+ const :unit, CarbonUnit, default: CarbonUnit::GRAM
11
+ const :items, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]) # @TODO: resolve to typed items?
12
+
13
+ sig { params(response_body: T::Hash[Symbol, T.untyped]).returns(Squake::Model::Carbon) }
14
+ def self.from_api_response(response_body)
15
+ Squake::Model::Carbon.new(
16
+ quantity: BigDecimal(String(response_body.fetch(:quantity))),
17
+ unit: CarbonUnit.deserialize(response_body.fetch(:unit)),
18
+ items: response_body.fetch(:items, nil),
19
+ )
20
+ end
21
+
22
+ sig do
23
+ params(
24
+ unit: CarbonUnit,
25
+ ).returns(Carbon)
26
+ end
27
+ def in!(unit)
28
+ # this is a bit hacky, but it optimizes memory usages and we don't need `T.must`
29
+ # everywhere if we were to use a prop instead of a const.
30
+ @quantity = CarbonUnit.convert(quantity, self.unit, to: unit)
31
+ @unit = unit
32
+ self
33
+ end
34
+
35
+ sig do
36
+ params(
37
+ other: Carbon,
38
+ ).returns(Carbon)
39
+ end
40
+ def +(other)
41
+ other_qty = CarbonUnit.convert(other.quantity, other.unit, to: CarbonUnit::GRAM)
42
+ self_qty = CarbonUnit.convert(quantity, unit, to: CarbonUnit::GRAM)
43
+
44
+ Carbon.new(quantity: other_qty + self_qty)
45
+ end
46
+
47
+ sig { returns(Numeric) }
48
+ def fractional
49
+ quantity.to_f.round(unit.precision)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,105 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ # as per International System of Units ("SI", or "metric system")
5
+ # see: https://www.nist.gov/pml/owm/si-units-mass
6
+ module Squake
7
+ module Model
8
+ class CarbonUnit < T::Enum
9
+ extend T::Sig
10
+
11
+ enums do
12
+ GRAM = new('gram')
13
+ KILOGRAM = new('kilogram')
14
+ TONNE = new('tonne')
15
+ end
16
+
17
+ sig { returns(String) }
18
+ def serialize_to_abbreviation
19
+ case self
20
+ when CarbonUnit::GRAM then 'g'
21
+ when CarbonUnit::KILOGRAM then 'kg'
22
+ when CarbonUnit::TONNE then 't'
23
+ else
24
+ T.absurd(self)
25
+ end
26
+ end
27
+
28
+ sig do
29
+ params(
30
+ carbon_quantity: T.any(Integer, Float, Rational, BigDecimal),
31
+ carbon_unit: CarbonUnit,
32
+ to: CarbonUnit,
33
+ ).returns(BigDecimal)
34
+ end
35
+ def self.convert(carbon_quantity, carbon_unit, to: CarbonUnit::GRAM)
36
+ case carbon_unit
37
+ when CarbonUnit::GRAM then gram_to_unit(carbon_quantity, to)
38
+ when CarbonUnit::KILOGRAM then kilogram_to_unit(carbon_quantity, to)
39
+ when CarbonUnit::TONNE then tonne_to_unit(carbon_quantity, to)
40
+ else
41
+ T.absurd(carbon_unit)
42
+ end
43
+ end
44
+
45
+ sig { returns(Integer) }
46
+ def precision
47
+ case self
48
+ when CarbonUnit::GRAM then 0
49
+ when CarbonUnit::KILOGRAM then 3
50
+ when CarbonUnit::TONNE then 6
51
+ else
52
+ T.absurd(self)
53
+ end
54
+ end
55
+
56
+ sig do
57
+ params(
58
+ carbon_quantity: T.any(Integer, Float, Rational, BigDecimal),
59
+ to: CarbonUnit,
60
+ ).returns(BigDecimal)
61
+ end
62
+ private_class_method def self.gram_to_unit(carbon_quantity, to)
63
+ case to
64
+ when CarbonUnit::GRAM then BigDecimal(carbon_quantity)
65
+ when CarbonUnit::KILOGRAM then BigDecimal(carbon_quantity) / 1_000
66
+ when CarbonUnit::TONNE then BigDecimal(carbon_quantity) / 1_000_000
67
+ else
68
+ T.absurd(to)
69
+ end
70
+ end
71
+
72
+ sig do
73
+ params(
74
+ carbon_quantity: T.any(Integer, Float, Rational, BigDecimal),
75
+ to: CarbonUnit,
76
+ ).returns(BigDecimal)
77
+ end
78
+ private_class_method def self.kilogram_to_unit(carbon_quantity, to)
79
+ case to
80
+ when CarbonUnit::GRAM then BigDecimal(carbon_quantity) * 1_000
81
+ when CarbonUnit::KILOGRAM then BigDecimal(carbon_quantity)
82
+ when CarbonUnit::TONNE then BigDecimal(carbon_quantity) / 1_000
83
+ else
84
+ T.absurd(to)
85
+ end
86
+ end
87
+
88
+ sig do
89
+ params(
90
+ carbon_quantity: T.any(Integer, Float, Rational, BigDecimal),
91
+ to: CarbonUnit,
92
+ ).returns(BigDecimal)
93
+ end
94
+ private_class_method def self.tonne_to_unit(carbon_quantity, to)
95
+ case to
96
+ when CarbonUnit::GRAM then BigDecimal(carbon_quantity) * 1_000_000
97
+ when CarbonUnit::KILOGRAM then BigDecimal(carbon_quantity) * 1_000
98
+ when CarbonUnit::TONNE then BigDecimal(carbon_quantity)
99
+ else
100
+ T.absurd(to)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Squake
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 'Team SQUAKE :rocket:'
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-14 00:00:00.000000000 Z
11
+ date: 2023-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -104,9 +104,12 @@ files:
104
104
  - README.md
105
105
  - lib/squake.rb
106
106
  - lib/squake/api_error.rb
107
+ - lib/squake/calculation.rb
107
108
  - lib/squake/calculation_with_pricing.rb
108
109
  - lib/squake/client.rb
109
110
  - lib/squake/config.rb
111
+ - lib/squake/model/carbon.rb
112
+ - lib/squake/model/carbon_unit.rb
110
113
  - lib/squake/model/items/base_type.rb
111
114
  - lib/squake/model/items/private_jet/squake.rb
112
115
  - lib/squake/model/price.rb