Skip to content

Commit 6113896

Browse files
committed
Merge branch 'release/0.1.1'
2 parents 8c1f6f5 + fa09850 commit 6113896

File tree

5 files changed

+43
-50
lines changed

5 files changed

+43
-50
lines changed

CHANGELOG.md

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

3+
## v0.1.1
4+
5+
* Do not make the type nullable when there is a default value
6+
37
## v0.1.0
48

59
* Initial version

README.md

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ defmodule Person do
3131
@type t() :: %__MODULE__{
3232
name: String.t(),
3333
age: non_neg_integer() | nil,
34-
happy?: boolean() | nil,
34+
happy?: boolean(),
3535
phone: String.t() | nil
3636
}
3737
end
@@ -41,7 +41,8 @@ In the example above you can notice several points:
4141

4242
* the keys are present in both the `defstruct` and type definition,
4343
* enforced keys must also be written in `@enforce_keys`,
44-
* if a key is not enforced, the type should be nullable.
44+
* if a key has no default value and is not enforced, its type should be
45+
nullable.
4546

4647
If you want to add a field in the struct, you must therefore:
4748

@@ -80,7 +81,7 @@ Thanks to TypedStruct, this is now possible :)
8081
To use TypedStruct in your project, add this to you Mix dependencies:
8182

8283
```elixir
83-
{:typed_struct, "~> 0.1.0", runtime: false}
84+
{:typed_struct, "~> 0.1.1", runtime: false}
8485
```
8586

8687
If you want to avoid `mix format` putting parentheses on field definitions,
@@ -168,7 +169,7 @@ iex(4)> Demo.__types__()
168169
[line: 5], []},
169170
nil
170171
]},
171-
with_default: {:|, [], [{:integer, [line: 6], []}, nil]}
172+
with_default: {:integer, [line: 6], []}
172173
]
173174
```
174175

@@ -234,32 +235,25 @@ field :name, String.t(), default: "John Smith"
234235
defstruct name: "John Smith"
235236
```
236237

237-
The type itself remains the same.
238-
239-
The `enforce` option, when set to `true`, enforces the key. Therefore, the
240-
type is not nullable anymore:
238+
When set to `true`, the `enforce` option enforces the key by adding it to the
239+
`@enforce_keys` attribute.
241240

242241
```elixir
243-
defmodule Example do
244-
use TypedStruct
242+
field :name, String.t(), enforce: true
245243

246-
typedstruct do
247-
field :name, String.t(), enforce: true
248-
end
249-
end
244+
# Becomes
245+
@enforce_keys [:name]
246+
defstruct name: nil
250247
```
251248

252-
becomes:
249+
In both cases, the type has no reason to be nullable anymore by default. In one
250+
case the field is filled with its default value and not `nil`, and in the other
251+
case it is enforced. Both options would generate the following type:
253252

254253
```elixir
255-
defmodule Example do
256-
@enforce_keys [:name] # :name is enforced
257-
defstruct name: nil
258-
259-
@type t() :: %__MODULE__{
260-
name: String.t() # Not nullable
261-
}
262-
end
254+
@type t() :: %__MODULE__{
255+
name: String.t() # Not nullable
256+
}
263257
```
264258

265259
## [Contributing](CONTRIBUTING.md)

lib/typed_struct.ex

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ defmodule TypedStruct do
2828
@type t() :: %__MODULE__{
2929
name: String.t(),
3030
age: non_neg_integer() | nil,
31-
happy?: boolean() | nil,
31+
happy?: boolean(),
3232
phone: String.t() | nil
3333
}
3434
end
@@ -37,7 +37,8 @@ defmodule TypedStruct do
3737
3838
* the keys are present in both the `defstruct` and type definition,
3939
* enforced keys must also be written in `@enforce_keys`,
40-
* if a key is not enforced, the type should be nullable.
40+
* if a key has no default value and is not enforced, its type should be
41+
nullable.
4142
4243
If you want to add a field in the struct, you must therefore:
4344
@@ -154,7 +155,7 @@ defmodule TypedStruct do
154155
[line: 5], []},
155156
nil
156157
]},
157-
with_default: {:|, [], [{:integer, [line: 6], []}, nil]}
158+
with_default: {:integer, [line: 6], []}
158159
]
159160
160161
## What do I get?
@@ -209,29 +210,22 @@ defmodule TypedStruct do
209210
# Becomes
210211
defstruct name: "John Smith"
211212
212-
The type itself remains the same.
213+
When set to `true`, the `enforce` option enforces the key by adding it to the
214+
`@enforce_keys` attribute.
213215
214-
The `enforce` option, when set to `true`, enforces the key. Therefore, the
215-
type is not nullable anymore:
216+
field :name, String.t(), enforce: true
216217
217-
defmodule Example do
218-
use TypedStruct
219-
220-
typedstruct do
221-
field :name, String.t(), enforce: true
222-
end
223-
end
224-
225-
becomes:
218+
# Becomes
219+
@enforce_keys [:name]
220+
defstruct name: nil
226221
227-
defmodule Example do
228-
@enforce_keys [:name] # :name is enforced
229-
defstruct name: nil
222+
In both cases, the type has no reason to be nullable anymore by default. In one
223+
case the field is filled with its default value and not `nil`, and in the other
224+
case it is enforced. Both options would generate the following type:
230225
231-
@type t() :: %__MODULE__{
232-
name: String.t() # Not nullable
233-
}
234-
end
226+
@type t() :: %__MODULE__{
227+
name: String.t() # Not nullable
228+
}
235229
"""
236230

237231
@doc false
@@ -304,9 +298,10 @@ defmodule TypedStruct do
304298

305299
default = opts[:default]
306300
enforce? = !!opts[:enforce]
301+
nullable? = !default && !enforce?
307302

308303
Module.put_attribute(mod, :fields, {name, default})
309-
Module.put_attribute(mod, :types, {name, type_for(type, enforce?)})
304+
Module.put_attribute(mod, :types, {name, type_for(type, nullable?)})
310305
if enforce?, do: Module.put_attribute(mod, :keys_to_enforce, name)
311306
end
312307

@@ -326,6 +321,6 @@ defmodule TypedStruct do
326321
##
327322

328323
# Makes the type nullable if the key is not enforced.
329-
defp type_for(type, true), do: type
324+
defp type_for(type, false), do: type
330325
defp type_for(type, _), do: quote(do: unquote(type) | nil)
331326
end

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule TypedStruct.MixProject do
22
use Mix.Project
33

4-
@version "0.1.0"
4+
@version "0.1.1"
55
@repo_url "https://github.com/ejpcmac/typed_struct"
66

77
def project do

test/typed_struct_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ defmodule TypedStructTest do
4242
@type t() :: %__MODULE__{
4343
int: integer() | nil,
4444
string: String.t() | nil,
45-
string_with_default: String.t() | nil,
45+
string_with_default: String.t(),
4646
mandatory_int: integer()
4747
}
4848
end
@@ -79,7 +79,7 @@ defmodule TypedStructTest do
7979
[
8080
int: integer() | nil,
8181
string: String.t() | nil,
82-
string_with_default: String.t() | nil,
82+
string_with_default: String.t(),
8383
mandatory_int: integer()
8484
]
8585
end

0 commit comments

Comments
 (0)