/
subject.jl
104 lines (75 loc) · 2.95 KB
/
subject.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
export SubjectTrait
export ValidSubject, InvalidSubject, as_subject
export AbstractSubjectFactory, create_subject
export InvalidSubjectTraitUsageError, InconsistentSubjectDataTypesError
export MissingCreateSubjectFactoryImplementationError
import Base: show
"""
Abstract type for all possible subject traits
See also: [`ValidSubject`](@ref), [`InvalidSubject`](@ref), [`as_subject`](@ref)
"""
abstract type SubjectTrait end
"""
Valid subject trait behavior
See also: [`SubjectTrait`](@ref)
"""
struct ValidSubject{D} <: SubjectTrait end
"""
Default subject trait behavior for all types.
See also: [`SubjectTrait`](@ref)
"""
struct InvalidSubject <: SubjectTrait end
"""
as_subject(::Type)
This function checks subject trait behavior specification. Should be used explicitly to specify subject trait behavior for any object type.
See also: [`SubjectTrait`](@ref)
"""
as_subject(::Type) = InvalidSubject()
# -------------------------------- #
# Subject factory #
# -------------------------------- #
"""
Abstract type for all possible subject factories
See also: [`SubjectTrait`](@ref), [`ValidSubject`](@ref), [`InvalidSubject`](@ref)
"""
abstract type AbstractSubjectFactory end
"""
create_subject(::Type{L}, factory::F) where L where { F <: AbstractSubjectFactory }
Actor creator function for a given factory `F`. Should be implemented explicitly for any `AbstractActorFactory` object
See also: [`AbstractSubjectFactory`](@ref), [`MissingCreateActorFactoryImplementationError`](@ref)
"""
create_subject(::Type{L}, factory::F) where L where { F <: AbstractSubjectFactory } = throw(MissingCreateSubjectFactoryImplementationError(factory))
"""
This error will be throw if Julia cannot find specific method of 'create_subject()' function for given subject factory
See also: [`AbstractSubjectFactory`](@ref), [`create_subject`](@ref)
"""
struct MissingCreateSubjectFactoryImplementationError
factory
end
function Base.show(io::IO, err::MissingCreateSubjectFactoryImplementationError)
print(io, "You probably forgot to implement create_subject(::Type{L}, factory::$(typeof(err.factory))).")
end
# -------------------------------- #
# Errors #
# -------------------------------- #
"""
InvalidSubject usage error
See also: [`as_subject`](@ref)
"""
struct InvalidSubjectTraitUsageError
subject
end
function Base.show(io::IO, err::InvalidSubjectTraitUsageError)
print(io, "Type $(typeof(err.subject)) is not a valid subject type. \nConsider implement as_subject(::Type{<:$(typeof(err.subject))}).")
end
"""
InconsistentSubjectDataTypesError
See also: [`as_subject`](@ref)
"""
struct InconsistentSubjectDataTypesError{T1, T2}
subject
end
function Base.show(io::IO, err::InconsistentSubjectDataTypesError{T1, T2}) where T1 where T2
# TODO: better error message
print(io, "Subject of type $(typeof(err.subject)) operates on data of type $(T2), while context requires subject to operate on data of type $(T1).")
end