/
package.scala
97 lines (85 loc) · 3.67 KB
/
package.scala
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
package com.twilio.guardrail.generators
import cats.data.NonEmptyList
import java.util.Locale
import io.swagger.v3.oas.models.{ Operation, PathItem }
import io.swagger.v3.oas.models.media.Schema
import io.swagger.v3.oas.models.parameters.Parameter
import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
import scala.language.implicitConversions
package syntax {
class RichNotNullShower[A](value: A) {
def showNotNull: String = showNotNullIndented(0)
def showNotNullIndented(indent: Int): String =
(" " * indent) + value.toString().linesIterator.filterNot(_.contains(": null")).mkString("\n" + (" " * indent))
}
class RichCollection[A, Repr](xs: IterableLike[A, Repr]){
def distinctBy[B, That](f: A => B)(implicit cbf: CanBuildFrom[Repr, A, That]) = {
val builder = cbf(xs.repr)
val i = xs.iterator
var set = Set[B]()
while (i.hasNext) {
val o = i.next
val b = f(o)
if (!set(b)) {
set += b
builder += o
}
}
builder.result
}
}
}
package object syntax {
val GENERATED_CODE_COMMENT_LINES: List[String] = List(
"This file was generated by Guardrail (https://github.com/twilio/guardrail).",
"Modifications will be overwritten; instead edit the OpenAPI/Swagger spec file."
)
/*
* The case converters work as follows.
*
* First we break up the given string into parts. This is a several-stage process
* while we consider boundaries in precedence order. First we split on
* dash/underscore/space/dot, as those are the "strongest" boundary delimiters.
* Then we split on non-uppercase -> uppercase boundaries. We avoid splitting
* just on uppercase because if a part is ALLUPPERCASE then we want to consider it
* a single part. After that, we try to keep runs of uppercase characters (when
* they are followed by non-uppercase characters) in the same group; that is,
* something like "FOOBar" should get broken up into ("foo", "bar").
*
* There are a few things we just can't accurately handle, like digits. If you
* consider the source string "foo9Bar", there's no way to know if that should
* be grouped as ("foo9", "bar") or ("foo", "9", "bar"). And for "foo9bar", it's
* worse: we don't know if it should be ("foo9bar"), ("foo", "9", "bar"),
* ("foo9", "bar"), or ("foo", "9bar"). In these cases we'll choose to assume
* that digits are not initial group characters.
*/
private val SPLIT_DELIMITERS = "[-_\\s\\.]+".r
private val BOUNDARY_SPLITTERS = List(
"([^A-Z])([A-Z])".r,
"([A-Z]+)([A-Z][^A-Z]+)".r
)
implicit class RichString(val s: String) extends AnyVal {
private def splitParts(s: String): List[String] =
BOUNDARY_SPLITTERS
.foldLeft(SPLIT_DELIMITERS.split(s))(
(last, splitter) => last.flatMap(part => splitter.replaceAllIn(part, m => m.group(1) + "-" + m.group(2)).split("-"))
)
.map(_.toLowerCase(Locale.US))
.toList
def toPascalCase: String = splitParts(s).map(_.capitalize).mkString
def toCamelCase: String =
NonEmptyList
.fromList(splitParts(s))
.fold("")(
parts => parts.head + parts.tail.map(_.capitalize).mkString
)
def toSnakeCase: String = splitParts(s).mkString("_")
def toDashedCase: String = splitParts(s).mkString("-")
}
implicit def RichSchema = new RichNotNullShower[Schema[_]](_)
implicit def RichOperation = new RichNotNullShower[Operation](_)
implicit def RichPathItem = new RichNotNullShower[PathItem](_)
implicit def RichParameter = new RichNotNullShower[Parameter](_)
implicit def toRichCollection[A, Repr](xs: IterableLike[A, Repr]) = new RichCollection(xs)
}