Section 2 - Letters
Restricting with Repeated
and Letter
But wait! The handles we made in section 1 don’t look very realistic. Only 15 letters are allowed for the username portion of the handle. Let’s update our specification:
import ropes.core._
type Username = Repeated[1, 15, Letter]
type TwitterHandle = Literal['@'] Concat Username
Being more precise, we’ve stated that the Username
must consist of
letter characters, repeated 1 to 15 times. It now will not allow
usernames which are too long or have non-letter characters:
Rope.parseTo[TwitterHandle]("@HowyP")
// res0: Either[Rope.InvalidValue.type, TwitterHandle] = Right(
// value = Concat(
// prefix = Literal(value = '@'),
// suffix = Repeated(
// values = List(
// First(value = CharacterClass(value = 'H')),
// Second(value = CharacterClass(value = 'o')),
// Second(value = CharacterClass(value = 'w')),
// Second(value = CharacterClass(value = 'y')),
// First(value = CharacterClass(value = 'P'))
// )
// )
// )
// )
Rope.parseTo[TwitterHandle]("@TwoManyCharactersForAUsername")
// res1: Either[Rope.InvalidValue.type, TwitterHandle] = Left(
// value = InvalidValue
// )
Rope.parseTo[TwitterHandle]("@foo&bar")
// res2: Either[Rope.InvalidValue.type, TwitterHandle] = Left(
// value = InvalidValue
// )
Now, let’s try generating some handles again:
import org.scalacheck.Arbitrary.arbitrary
import ropes.scalacheck._
List.fill(5)(arbitrary[TwitterHandle].sample).flatten.map(_.write + '\n')
// res3: List[String] = List(
// """@fpuZklUDFin
// """,
// """@syWdaCXUJWTPUIu
// """,
// """@q
// """,
// """@zMAZLuDJqjXtCrJ
// """,
// """@fpGJhiuiVNUun
// """
// )
Restricting allowed characters with Range
Letter
comes pre-defined in ropes as:
type Letter = Letter.Uppercase Or Letter.Lowercase
object Letter {
type Uppercase = Range['A', 'Z']
type Lowercase = Range['a', 'z']
}
It defines the upper and lower case characters using a Range
, which
takes two literal type parameters specifying the minimum and maximum
characters allowed. Or
lets us to join the two, allowing characters
from either range.