1
struct EnumerableDefaultIfEmpty{T,S} <: Enumerable
2 47
    source::S
3
    default_value::T
4
end
5

6 0
Base.eltype(iter::Type{EnumerableDefaultIfEmpty{T,S}}) where {T,S} = T
7

8 0
_default_value_expr(::Type{T}) where {T} = :( DataValues.DataValue{$T}() )
9

10 47
_default_value_expr(::Type{T}) where {T<:DataValues.DataValue} = :( $T() )
11

12
function _default_value_expr(::Type{T}) where {T<:NamedTuple}
13 47
    return :( NamedTuple{$(fieldnames(T))}( ($( (_default_value_expr(fieldtype(T,i)) for i in 1:length(fieldnames(T)))...   ),)) )
14
end
15

16
@generated function default_if_empty(source::S) where {S}
17 47
    T_source = eltype(source)
18

19 47
    default_value_expr = _default_value_expr(T_source)
20

21 47
    q = quote
22 39
        default_value = $default_value_expr
23

24
        T = typeof(default_value)
25

26 47
        return EnumerableDefaultIfEmpty{T,$S}(source, default_value)
27
    end
28

29 47
    return q
30
end
31

32

33
function default_if_empty(source::S, default_value::TD) where {S,TD}
34 47
    T = eltype(source)
35
    if T!=TD
36 47
        error("The default value must have the same type as the elements from the source.")
37
    end
38 47
    return EnumerableDefaultIfEmpty{T,S}(source, default_value)
39
end
40

41
function Base.iterate(iter::EnumerableDefaultIfEmpty{T,S}) where {T,S}
42 47
    s = iterate(iter.source)
43

44 47
    if s===nothing
45 17
        return iter.default_value, nothing
46
    else
47 47
        return convert(T,s[1]), s[2]
48
    end
49
end
50

51
function Base.iterate(iter::EnumerableDefaultIfEmpty{T,S}, state) where {T,S}
52 47
    state===nothing && return nothing
53

54 47
    s = iterate(iter.source, state)
55 47
    if s===nothing
56 47
        return nothing
57
    else
58 47
        return convert(T, s[1]), s[2]
59
    end
60
end

Read our documentation on viewing source code .

Loading