Skip to content

Commit 03ff840

Browse files
Merge pull request #11 from kommitters/v0.1.3-dev
Release 0.1.3
2 parents 1bde39d + 94e6fae commit 03ff840

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2026
-874
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 0.1.3 (22.05.2020)
4+
5+
* Increase test coverage to 100%
6+
* The encode_xdr() and decode_xdr() functions now return error tuples
7+
* The encode_xdr!() and decode_xdr!() functions raise the errors
8+
* Add examples of all the XDR-types to README
9+
* Add examples to Hexdocs
10+
* Remove Anti-Patterns
11+
312
## 0.1.2 (18.05.2020)
413

514
* Add support for older Elixir versions strating from 1.7.0.

README.md

Lines changed: 260 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,16 @@ XDR.Optional # Section 4.19
4848
```
4949
XDR.QuadFloat # Section 4.8, not supported for 128-byte size.
5050
XDR.Const # Section 4.17, can be replaced with elixir constants.
51-
XDR.Typedef # Section 4.18, may be implemented with elixir modules. More info bellow in this guude.
51+
XDR.Typedef # Section 4.18, may be implemented with elixir modules. More info bellow in this guide.
5252
```
5353

54-
## How to implement a XDR type?
54+
## Better without macros
55+
56+
`It is an Open Source project, not a code that only I understand`
57+
58+
Macros are harder to write than ordinary Elixir functions, implementing them increases the code complexity which is not good especially if you are planning to build an Open Source code easy to understand to everyone. We decided to go without macros, we want to let everyone to expand or implement their own XDR types with a clear model based on Elixir functions.
59+
60+
## How to implement an XDR type?
5561
**Behavior is the key**. When implementing a new XDR type follow this [Behavior's Declaration](https://github.com/kommitters/elixir_xdr/blob/develop/lib/xdr/declaration.ex).
5662

5763
## Decoding output
@@ -62,7 +68,9 @@ iex> XDR.Int.decode_xdr!(<<0, 0, 4, 210, 5>>)
6268
```
6369

6470
## Usage examples
65-
### XDR.Int
71+
As mentioned before all the XDR types follow the same [Behavior's Declaration](https://github.com/kommitters/elixir_xdr/blob/develop/lib/xdr/declaration.ex)
72+
73+
### Integer
6674
For encoding integers use `encode_xdr/2` or use the raising version of the function `encode_xdr!/2`.
6775
```elixir
6876
iex> XDR.Int.new(1234) |> XDR.Int.encode_xdr()
@@ -80,8 +88,63 @@ iex> XDR.Int.decode_xdr!(<<0, 0, 4, 210>>)
8088
{%XDR.Int{datum: 1234}, <<>>}
8189
```
8290

83-
### XDR.Bool
84-
As mentioned before all the XDR types follow the same [Behavior's Declaration](https://github.com/kommitters/elixir_xdr/blob/develop/lib/xdr/declaration.ex)
91+
### Unsigned Integer
92+
93+
Represents integer values in a range of `[0, 4294967295]`.
94+
95+
For encoding
96+
```elixir
97+
iex> XDR.UInt.new(564) |> XDR.UInt.encode_xdr()
98+
{:ok, <<0, 0, 2, 52>>}
99+
100+
iex> XDR.UInt.new(564) |> XDR.UInt.encode_xdr!()
101+
<<0, 0, 2, 52>>
102+
103+
```
104+
105+
For decoding
106+
```elixir
107+
iex> XDR.UInt.decode_xdr(<<0, 0, 2, 52>>)
108+
{:ok, {%XDR.UInt{datum: 564}, <<>>}}
109+
110+
iex> XDR.UInt.decode_xdr!(<<0, 0, 2, 52>>)
111+
{%XDR.UInt{datum: 564}, <<>>}
112+
```
113+
114+
### Enumeration
115+
116+
Represents subsets of integers.
117+
118+
**Implementation**
119+
120+
Enums are keywords lists containing a set of **declarations (statically defined)** and a **identifier** with the key of the selected declaration. The [XDR.Bool](https://github.com/kommitters/elixir_xdr/blob/develop/lib/xdr/bool.ex) is a clear example of an Enum implementation.
121+
122+
```elixir
123+
declarations = [false: 0, true: 1]
124+
```
125+
Now, you could decide the key to select
126+
127+
For encoding
128+
```elixir
129+
iex> XDR.Enum.new([false: 0, true: 1], :false) |> XDR.Enum.encode_xdr()
130+
{:ok, <<0, 0, 0, 0>>}
131+
132+
iex> XDR.Enum.new([false: 0, true: 1], :true) |> XDR.Enum.encode_xdr!()
133+
<<0, 0, 0, 1>>
134+
```
135+
136+
For decoding
137+
```elixir
138+
iex> XDR.Enum.decode_xdr(<<0, 0, 0, 1>>, %{declarations: [false: 0, true: 1]})
139+
{:ok, {%XDR.Enum{declarations: [false: 0, true: 1], identifier: true}, <<>>}}
140+
141+
iex> XDR.Enum.decode_xdr!(<<0, 0, 0, 1>>, %{declarations: [false: 0, true: 1]})
142+
{%XDR.Enum{declarations: [false: 0, true: 1], identifier: true}, <<>>}
143+
```
144+
145+
### Boolean
146+
Boolean is an Enum implementation that allows us to create boolean types
147+
85148
```elixir
86149
iex> XDR.Bool.new(true) |> XDR.Bool.encode_xdr()
87150
{:ok, <<0, 0, 0, 0>>}
@@ -98,16 +161,92 @@ iex> XDR.Bool.decode_xdr!(<<0, 0, 0, 1>>)
98161
{%XDR.Bool{declarations: [false: 0, true: 1], identifier: true}, ""}
99162
```
100163

101-
### XDR.Enum
102-
Enums are keywords lists containing a set of **declarations (statically defined)** and a **indentifier** with the key of the selected declaration.
164+
### Hyper Integer
165+
166+
Represents integer values in a range of `[-9223372036854775808, 9223372036854775807]`
167+
168+
For encoding
169+
170+
```elixir
171+
iex> XDR.HyperInt.new(258963) |> XDR.HyperInt.encode_xdr()
172+
{:ok, <<0, 0, 0, 0, 0, 3, 243, 147>>}
103173

104-
The [XDR.Bool](https://github.com/kommitters/elixir_xdr/blob/develop/lib/xdr/bool.ex) is a clear example of an Enum implementation.
174+
iex> XDR.HyperInt.new(258963) |> XDR.HyperInt.encode_xdr!()
175+
<<0, 0, 0, 0, 0, 3, 243, 147>>
176+
```
177+
For encoding
105178
```elixir
106-
iex> XDR.Bool.decode_xdr!<<0, 0, 0, 1>>)
107-
{%XDR.Bool{declarations: [false: 0, true: 1], identifier: true}, ""}
179+
iex> XDR.HyperInt.decode_xdr(<<0, 0, 0, 0, 0, 3, 243, 147>>)
180+
{:ok, {%XDR.HyperInt{datum: 258963}, <<>>}}
181+
182+
iex> XDR.HyperInt.decode_xdr!(<<0, 0, 0, 0, 0, 3, 243, 147>>)
183+
{%XDR.HyperInt{datum: 258963}, <<>>}
184+
```
185+
186+
### Unsigned Hyper Integer
187+
188+
Represents integer values in a range of `[0, 18446744073709551615]`
189+
190+
For encoding
191+
```elixir
192+
iex> XDR.HyperUInt.new(258963) |> XDR.HyperUInt.encode_xdr()
193+
{:ok, <<0, 0, 0, 0, 0, 3, 243, 147>>}
194+
195+
iex> XDR.HyperUInt.new(258963) |> XDR.HyperUInt.encode_xdr!()
196+
<<0, 0, 0, 0, 0, 3, 243, 147>>
197+
```
198+
For decoding
199+
```elixir
200+
iex> XDR.HyperUInt.decode_xdr(<<0, 0, 0, 0, 0, 3, 243, 147>>)
201+
{:ok, {%XDR.HyperUInt{datum: 258963}, <<>>}}
202+
203+
iex> XDR.HyperUInt.decode_xdr!(<<0, 0, 0, 0, 0, 3, 243, 147>>)
204+
{%XDR.HyperUInt{datum: 258963}, <<>>}
108205
```
109206

110-
### XDR.FixedOpaque
207+
### Floating Point
208+
209+
Represents single-precision float values (32 bits, 4 bytes)
210+
211+
For encoding
212+
```elixir
213+
iex> XDR.Float.new(3.46) |> XDR.Float.encode_xdr()
214+
{:ok, <<64, 93, 112, 164>>}
215+
216+
iex> XDR.Float.new(258963) |> XDR.Float.encode_xdr!()
217+
<<64, 93, 112, 164>>
218+
```
219+
For decoding
220+
```elixir
221+
iex> XDR.Float.decode_xdr(<<64, 93, 112, 164>>)
222+
{:ok, {%XDR.Float{float: 3.4600000381469727}, <<>>}}
223+
224+
iex> XDR.Float.decode_xdr!(<<64, 93, 112, 164>>)
225+
{%XDR.Float{float: 3.4600000381469727}, <<>>}
226+
```
227+
228+
### Double-Floating Point
229+
230+
Represents Double-precision float values (64 bits, 8 bytes)
231+
232+
For encoding
233+
```elixir
234+
iex> XDR.DoubleFloat.new(3.46) |> XDR.DoubleFloat.encode_xdr()
235+
{:ok, <<64, 11, 174, 20, 122, 225, 71, 174>>}
236+
237+
iex> XDR.DoubleFloat.new(258963) |> XDR.DoubleFloat.encode_xdr!()
238+
<<64, 11, 174, 20, 122, 225, 71, 174>>
239+
```
240+
For decoding
241+
```elixir
242+
iex> XDR.DoubleFloat.decode_xdr(<<64, 11, 174, 20, 122, 225, 71, 174>>)
243+
{:ok, {%XDR.DoubleFloat{float: 3.46}, <<>>}}
244+
245+
iex> XDR.DoubleFloat.decode_xdr!(<<64, 11, 174, 20, 122, 225, 71, 174>>)
246+
{:ok, {%XDR.DoubleFloat{float: 3.46}, <<>>}}
247+
```
248+
249+
### Fixed-Length Opaque
111250
FixedOpaque is used for fixed-length uninterpreted data that needs to be passed among machines, in other words, let's think on a string that must match a fixed length.
112251

113252
```elixir
@@ -116,7 +255,28 @@ iex> ComplementBinarySize.new(<<1,2,3,4,5>>) |> ComplementBinarySize.encode_xdr(
116255
```
117256
An example is available here: [FixedOpaque Type](https://github.com/kommitters/elixir_xdr/wiki/FixedOpaque-example).
118257

119-
### XDR.String
258+
### Variable-Length Opaque
259+
260+
Represents a sequence of n (numbered 0 through n-1) arbitrary bytes to be the number n encoded as an unsigned integer
261+
262+
For encoding
263+
```elixir
264+
iex> XDR.VariableOpaque.new(<<1, 2, 3, 4, 5>>) |> XDR.VariableOpaque.encode_xdr()
265+
{:ok, <<0, 0, 0, 5, 1, 2, 3, 4, 5, 0, 0, 0>>}
266+
267+
iex> XDR.VariableOpaque.new(<<1, 2, 3>>, 3) |> XDR.VariableOpaque.encode_xdr!()
268+
<<0, 0, 0, 3, 1, 2, 3, 0>>
269+
```
270+
For decoding
271+
```elixir
272+
iex> XDR.VariableOpaque.decode_xdr(<<0, 0, 0, 5, 1, 2, 3, 4, 5, 0, 0, 0>>, %{max_size: 5})
273+
{:ok, {%XDR.VariableOpaque{max_size: 5, opaque: <<1, 2, 3, 4, 5>>}, <<>>}}
274+
275+
iex> XDR.VariableOpaque.decode_xdr!(<<0, 0, 0, 5, 1, 2, 3, 4, 5, 0, 0, 0>>, %{max_size: 5})
276+
{%XDR.VariableOpaque{max_size: 5, opaque: <<1, 2, 3, 4, 5>>}, <<>>}
277+
```
278+
279+
### String
120280
For econding strings.
121281
```elixir
122282
iex> XDR.String.new("The little prince") |> XDR.String.encode_xdr()
@@ -139,7 +299,63 @@ iex> XDR.String.decode_xdr!(<<0, 0, 0, 17, 84, 104, 101, 32, 108, 105, 116, 116,
139299
{%XDR.String{max_length: 4294967295, string: "The little prince"}, ""}
140300
```
141301

142-
### XDR.Struct
302+
### Fixed-Length Array
303+
304+
Represents a Fixed-Length array that contains the same type of elements
305+
306+
For encoding
307+
```elixir
308+
iex> XDR.FixedArray.new([1,2,3], XDR.Int, 3) |> XDR.FixedArray.encode_xdr()
309+
{:ok, <<0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3>>}
310+
311+
iex> XDR.FixedArray.new(["The", "little", "prince"], XDR.String, 3) |> XDR.FixedArray.encode_xdr!()
312+
<<0, 0, 0, 3, 84, 104, 101, 0, 0, 0, 0, 6, 108, 105, 116, 116, 108, 101, 0, 0,
313+
0, 0, 0, 6, 112, 114, 105, 110, 99, 101, 0, 0>>
314+
```
315+
For decoding
316+
```elixir
317+
iex> XDR.FixedArray.decode_xdr(<<0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3>>, %{type: XDR.Int, length: 3})
318+
{:ok, {[%XDR.Int{datum: 1}, %XDR.Int{datum: 2}, %XDR.Int{datum: 3}], <<>>}}
319+
320+
iex> XDR.FixedArray.decode_xdr!(<<0, 0, 0, 3, 84, 104, 101, 0, 0, 0, 0, 6, 108, 105, 116, 116, 108,
321+
101, 0, 0, 0, 0, 0, 6, 112, 114, 105, 110, 99, 101, 0, 0>>, %{type: XDR.String, length: 3})
322+
{[
323+
%XDR.String{max_length: 4294967295, string: "The"},
324+
%XDR.String{max_length: 4294967295, string: "little"},
325+
%XDR.String{max_length: 4294967295, string: "prince"}
326+
], <<>>}
327+
```
328+
329+
### Variable-Length Array
330+
331+
Represents a variable-length array which contains the same type of elements
332+
333+
For encoding
334+
```elixir
335+
iex> XDR.VariableArray.new([1,2,3], XDR.Int) |> XDR.VariableArray.encode_xdr()
336+
{:ok, <<0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3>>}
337+
338+
iex> XDR.VariableArray.new(["The", "little", "prince"], XDR.String) |> XDR.VariableArray.encode_xdr!()
339+
<<0, 0, 0, 3, 0, 0, 0, 3, 84, 104, 101, 0, 0, 0, 0, 6, 108, 105, 116, 116, 108,
340+
101, 0, 0, 0, 0, 0, 6, 112, 114, 105, 110, 99, 101, 0, 0>>
341+
```
342+
For decoding
343+
```elixir
344+
iex> XDR.VariableArray.decode_xdr(<<0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3>>,
345+
...> %{type: XDR.Int, max_length: 3})
346+
{:ok, {[%XDR.Int{datum: 1}, %XDR.Int{datum: 2}, %XDR.Int{datum: 3}], <<>>}}
347+
348+
iex> XDR.VariableArray.decode_xdr!(<<0, 0, 0, 3, 0, 0, 0, 3, 84, 104, 101, 0, 0, 0, 0, 6, 108, 105,
349+
...> 116, 116, 108, 101, 0, 0, 0, 0, 0, 6, 112, 114, 105, 110, 99, 101, 0, 0>>,
350+
...> %{type: XDR.String, length: 3})
351+
{[
352+
%XDR.String{max_length: 4294967295, string: "The"},
353+
%XDR.String{max_length: 4294967295, string: "little"},
354+
%XDR.String{max_length: 4294967295, string: "prince"}
355+
], <<>>}
356+
```
357+
358+
### Structure
143359
```elixir
144360
iex(1)> name = XDR.String.new("The little prince")
145361
%XDR.String{max_length: 4294967295, string: "The little prince"}
@@ -154,8 +370,7 @@ iex(3)> Book.new(name, size) |> Book.encode_xdr()
154370
```
155371
An example is available here: [Struct Type](https://github.com/kommitters/elixir_xdr/wiki/Struct-example).
156372

157-
158-
### XDR.Union
373+
### Union
159374
A union is a type composed of a discriminant **(Statement)** followed by a type selected from a set of prearranged types **(UnionStatement)**. The type of discriminant is either "Int", "Unsigned Int", or an Enumerated type, such as "Bool". The **(UnionStatement)** types are called "arms" of the union and are preceded by the value of the discriminant that implies their encoding.
160375

161376
```elixir
@@ -168,15 +383,37 @@ iex(3)> XDR.UnionStatement.decode_xdr(<<0, 0, 0, 3, 64, 93, 112, 164>>)
168383

169384
An example is available here: [Union Example](https://github.com/kommitters/elixir_xdr/wiki/Union-example)
170385

171-
### XDR.Optional
386+
### Void
387+
388+
Represents the void types or nil in elixir case
389+
390+
For encoding
391+
```elixir
392+
iex> XDR.Void.new(nil) |> XDR.Void.encode_xdr()
393+
{:ok, <<>>}
394+
395+
iex> XDR.Void.new(nil) |> XDR.Void.encode_xdr!()
396+
<<>>
397+
```
398+
For decoding
399+
```elixir
400+
iex> XDR.Void.decode_xdr(<<>>)
401+
{:ok, {nil, <<>>}}
402+
403+
iex> XDR.Void.decode_xdr!(<<>>)
404+
{nil, <<>>}
405+
```
406+
407+
### Optional
408+
Think that you are filling out a form and it has optional fields such as the phone number if you do not want to fill this field you can leave it empty and the field will have a nil value, on the contrary, if you want to fill it out you can do it and it will take the indicated value
409+
172410
```elixir
173-
iex(1)> XDR.String.new("Hello") |> OptionalString.new() |> OptionalString.encode_xdr()
174-
{:ok, <<0, 0, 0, 1, 0, 0, 0, 5, 72, 101, 108, 108, 111, 0, 0, 0>>}
411+
iex(1)> XDR.String.new("phone number") |> OptionalString.new() |> OptionalString.encode_xdr()
412+
{:ok, <<0, 0, 0, 1, 0, 0, 0, 12, 112, 104, 111, 110, 101, 32, 110, 117, 109, 98, 101, 114>>}
175413

176-
iex(2)> OptionalString.decode_xdr(<<0, 0, 0, 1, 0, 0, 0, 5, 72, 101, 108, 108, 111, 0, 0, 0>>)
414+
iex(2)> OptionalString.decode_xdr(<<0, 0, 0, 1, 0, 0, 0, 12, 112, 104, 111, 110, 101, 32, 110, 117, 109, 98, 101, 114>>)
177415
{:ok,
178-
{%XDR.Optional{type: %XDR.String{max_length: 4294967295, string: "Hello"}}, ""}}
179-
416+
{%XDR.Optional{type: %XDR.String{max_length: 4294967295, string: "phone number"}}, ""}}
180417
iex(3)> OptionalString.new(nil) |> OptionalString.encode_xdr()
181418
{:ok, <<0, 0, 0, 0>>}
182419

@@ -195,10 +432,10 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/kommit
195432
Everyone is welcome to participate in the project.
196433

197434
## Changelog
198-
See the [CHANGELOG](https://github.com/kommitters/elixir_xdr/blob/master/CHENGELOG.md) for versions details.
435+
See the [CHANGELOG](https://github.com/kommitters/elixir_xdr/blob/master/CHANGELOG.md) for versions details.
199436

200437
## License
201438
See [LICENSE](https://github.com/kommitters/elixir_xdr/blob/master/LICENSE) for details.
202439

203440
## Credits
204-
Made with 💙 from [kommit](https://kommit.co)
441+
Made with 💙 from [kommit](https://kommit.co)

guides/examples/boolean.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Boolean
2+
3+
It is an Enum implementation to represent the boolean values
4+
5+
## Usage
6+
7+
### Encoding
8+
9+
```elixir
10+
iex> XDR.Bool.new(false) |> XDR.Bool.encode_xdr()
11+
{:ok, <<0, 0, 0, 0>>}
12+
13+
iex> XDR.Bool.new(true) |> XDR.Bool.encode_xdr!()
14+
<<0, 0, 0, 1>>
15+
```
16+
17+
### Decoding
18+
19+
```elixir
20+
iex> XDR.Bool.decode_xdr(<<0, 0, 0, 0>>)
21+
{:ok, {%XDR.Bool{declarations: [false: 0, true: 1], identifier: false}, <<>>}}
22+
23+
iex> XDR.Bool.decode_xdr!(<<0, 0, 0, 1>>)
24+
{%XDR.Bool{declarations: [false: 0, true: 1], identifier: true}, <<>>}
25+
```

0 commit comments

Comments
 (0)