@@ -4,68 +4,107 @@ import java.nio.file.Path
4
4
5
5
import play .api .libs .json ._
6
6
7
+ import scala .language .reflectiveCalls
7
8
import scala .util .Try
8
9
9
10
package dockerApi {
10
11
11
- abstract class Formats [W <: AnyVal { val value : B },B ](apply_ : (B => W )) extends (B => W ){ self =>
12
+ abstract class Formats [W <: AnyVal {val value : B }, B ](apply_ : (B => W )) extends (B => W ) {
13
+ self =>
12
14
13
- implicit def writes (implicit writes : Writes [B ]): Writes [W ] = Writes (
14
- (_:W ).value match { case value: B @ unchecked => writes.writes(value) }
15
- )
15
+ implicit def writes (implicit writes : Writes [B ]): Writes [W ] = Writes (
16
+ (_ : W ).value match { case value : B @ unchecked => writes.writes(value) }
17
+ )
16
18
17
- implicit def reads (implicit reads : Reads [B ]): Reads [W ] = reads.map( self.apply )
19
+ implicit def reads (implicit reads : Reads [B ]): Reads [W ] = reads.map(self.apply)
18
20
19
- override def apply (v1 : B ): W = apply_(v1)
20
- }
21
+ override def apply (v1 : B ): W = apply_(v1)
22
+ }
23
+
24
+ trait Tool {
25
+ def apply (path : Path , conf : Option [Seq [PatternDef ]], files : Option [Set [Path ]])(implicit spec : Spec ): Try [Iterable [Result ]]
26
+ }
27
+
28
+ final class PatternId (val value : String ) extends AnyVal {
29
+ override def toString = value.toString
30
+ }
31
+
32
+ final class SourcePath (val value : String ) extends AnyVal {
33
+ override def toString = value.toString
34
+ }
35
+
36
+ final class ResultMessage (val value : String ) extends AnyVal {
37
+ override def toString = value.toString
38
+ }
39
+
40
+ final class ResultLine (val value : Int ) extends AnyVal {
41
+ override def toString = value.toString
42
+ }
43
+
44
+ final class ToolName (val value : String ) extends AnyVal {
45
+ override def toString = value.toString
46
+ }
47
+
48
+ final class ErrorMessage (val value : String ) extends AnyVal {
49
+ override def toString = value.toString
50
+ }
51
+
52
+ final class ParameterName (val value : String ) extends AnyVal {
53
+ override def toString = value.toString
54
+ }
55
+
56
+ object PatternId extends Formats [PatternId , String ](new PatternId (_))
57
+
58
+ object SourcePath extends Formats [SourcePath , String ](new SourcePath (_))
59
+
60
+ object ResultMessage extends Formats [ResultMessage , String ](new ResultMessage (_))
61
+
62
+ object ResultLine extends Formats [ResultLine , Int ](new ResultLine (_))
63
+
64
+ object ToolName extends Formats [ToolName , String ](new ToolName (_))
65
+
66
+ object ErrorMessage extends Formats [ErrorMessage , String ](new ErrorMessage (_))
67
+
68
+ object ParameterName extends Formats [ParameterName , String ](new ParameterName (_))
69
+
70
+ case class ParameterDef (name : ParameterName , value : JsValue )
71
+
72
+ case class PatternDef (patternId : PatternId , parameters : Option [Set [ParameterDef ]])
73
+
74
+ case class ToolConfig (name : ToolName , patterns : Seq [PatternDef ])
75
+
76
+ private [dockerApi] case class FullConfig (tools : Set [ToolConfig ], files : Option [Set [SourcePath ]])
77
+
78
+ // there are other fields like name and description but i don't care about them inside the tool
79
+ case class ParameterSpec (name : ParameterName , default : JsValue )
80
+
81
+ case class PatternSpec (patternId : PatternId , parameters : Option [Set [ParameterSpec ]])
82
+
83
+ case class Spec (name : ToolName , patterns : Set [PatternSpec ])
84
+
85
+ sealed trait Result
86
+
87
+ final case class Issue (filename : SourcePath , message : ResultMessage , patternId : PatternId , line : ResultLine ) extends Result
88
+
89
+ final case class FileError (filename : SourcePath , message : Option [ErrorMessage ]) extends Result
21
90
22
- trait Tool { def apply (path : Path ,conf : Option [Seq [PatternDef ]], files: Option [Set [Path ]])(implicit spec : Spec ): Try [Iterable [Result ]] }
23
- final class PatternId (val value : String ) extends AnyVal { override def toString = value.toString }
24
- final class SourcePath (val value : String ) extends AnyVal { override def toString = value.toString }
25
- final class ResultMessage (val value : String ) extends AnyVal { override def toString = value.toString }
26
- final class ResultLine (val value : Int ) extends AnyVal { override def toString = value.toString }
27
- final class ToolName (val value : String ) extends AnyVal { override def toString = value.toString }
28
- final class ErrorMessage (val value : String ) extends AnyVal { override def toString = value.toString }
29
- final class ParameterName (val value : String ) extends AnyVal { override def toString = value.toString }
30
-
31
- object PatternId extends Formats [PatternId , String ]( new PatternId (_) )
32
- object SourcePath extends Formats [SourcePath , String ]( new SourcePath (_) )
33
- object ResultMessage extends Formats [ResultMessage , String ]( new ResultMessage (_) )
34
- object ResultLine extends Formats [ResultLine , Int ]( new ResultLine (_) )
35
- object ToolName extends Formats [ToolName , String ]( new ToolName (_) )
36
- object ErrorMessage extends Formats [ErrorMessage , String ]( new ErrorMessage (_) )
37
- object ParameterName extends Formats [ParameterName , String ]( new ParameterName (_) )
38
-
39
- case class ParameterDef (name: ParameterName ,value: JsValue )
40
- case class PatternDef (patternId : PatternId , parameters: Option [Set [ParameterDef ]])
41
- case class ToolConfig (name: ToolName , patterns: Seq [PatternDef ])
42
-
43
- private [dockerApi] case class FullConfig (tools: Set [ToolConfig ],files: Option [Set [SourcePath ]])
44
- // there are other fields like name and description but i don't care about them inside the tool
45
- case class ParameterSpec (name: ParameterName , default: JsValue )
46
- case class PatternSpec (patternId : PatternId , parameters: Option [Set [ParameterSpec ]])
47
-
48
- case class Spec (name: ToolName ,patterns: Set [PatternSpec ])
49
-
50
- sealed trait Result
51
- final case class Issue (filename: SourcePath , message: ResultMessage , patternId: PatternId , line : ResultLine ) extends Result
52
- final case class FileError (filename: SourcePath , message: Option [ErrorMessage ]) extends Result
53
91
}
54
92
55
93
package object dockerApi {
56
94
57
- private [this ] def asReader [A ](jsResult : JsResult [A ]): Reads [A ] = Reads [A ]((_:JsValue ) => jsResult)
58
- implicit def toValue [A ] = (a: AnyVal { def value : A }) => a.value
95
+ private [this ] def asReader [A ](jsResult : JsResult [A ]): Reads [A ] = Reads [A ]((_ : JsValue ) => jsResult)
96
+
97
+ implicit def toValue [A ] = (a : AnyVal {def value : A }) => a.value
59
98
60
99
implicit lazy val specReader : Reads [Spec ] = {
61
100
implicit val r1 = Json .reads[ParameterSpec ]
62
101
implicit val r0 = Json .reads[PatternSpec ]
63
102
Json .reads[Spec ]
64
103
}
65
104
66
- implicit def configReader (implicit spec: Spec ): Reads [FullConfig ] = {
105
+ implicit def configReader (implicit spec : Spec ): Reads [FullConfig ] = {
67
106
implicit val r1 = Json .reads[ParameterDef ]
68
- implicit val r0 = Json .reads[PatternDef ]/* .flatMap{ case pattern =>
107
+ implicit val r0 = Json .reads[PatternDef ] /* .flatMap{ case pattern =>
69
108
70
109
val filtered =
71
110
if (spec.patterns.exists(_.patternId == pattern.patternId)) JsSuccess(pattern)
@@ -76,7 +115,7 @@ package object dockerApi {
76
115
77
116
implicit val r2 = Reads .set(Json .reads[ToolConfig ])
78
117
79
- Json .reads[FullConfig ]/* .flatMap{ case fullCfg =>
118
+ Json .reads[FullConfig ] /* .flatMap{ case fullCfg =>
80
119
val ps = fullCfg.tools.collectFirst{ case tool if tool.name == spec.name =>
81
120
if(tool.patterns.isEmpty) JsError("no patterns selected")
82
121
else JsSuccess(fullCfg)
@@ -90,14 +129,14 @@ package object dockerApi {
90
129
lazy val issueWrites = Json .writes[Issue ]
91
130
lazy val errorWrites = Json .writes[FileError ]
92
131
93
- Writes [Result ]{ (result: Result ) =>
94
- val base = result match {
95
- case issue: Issue => issueWrites.writes(issue)
96
- case error: FileError => errorWrites.writes(error)
132
+ Writes [Result ] { (result : Result ) =>
133
+ val base = result match {
134
+ case issue : Issue => issueWrites.writes(issue)
135
+ case error : FileError => errorWrites.writes(error)
97
136
}
98
137
99
- (base,result.getClass.getTypeName.split('.' ).lastOption) match {
100
- case (o: JsObject ,Some (tpe)) => o ++ Json .obj(" type" -> tpe )
138
+ (base, result.getClass.getTypeName.split('.' ).lastOption) match {
139
+ case (o : JsObject , Some (tpe)) => o ++ Json .obj(" type" -> tpe)
101
140
case other => base
102
141
}
103
142
}
0 commit comments