Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package taglessfinal
- import java.util.UUID
- import cats.MonadError
- import cats.implicits._
- import external.{ExternalLocation, GoogleLocation}
- import model.{Coordinates, Location}
- /**
- * @author Alexander Isakov
- */
- trait LocationService[F[_]] {
- protected val googleLocationService: GoogleLocationService[F]
- //
- def get(normalizedName: String, coordinate: Coordinates): F[Location]
- def get(placeId: String): F[Location]
- def create(el: ExternalLocation): F[Location] = {
- for {
- _ <- el.coordinates
- .map(c => get(normalize(el.name), c))
- .fold(().pure[F])(fl => ME.ifM(fl.map(_ => true))(ME.raiseError(DuplicateLocationException), ().pure[F]))
- address <- el.address
- .map(a => a.trim)
- .filter(a => a.nonEmpty)
- .fold(ME.raiseError[String](InvalidLocationArgumentsError))(_.pure[F])
- gl <- googleLocationService
- .getByAddress(s"${el.name} $address")
- result <- ME.ifM(get(gl.placeId).map(_ => true))(
- ME.raiseError[Location](DuplicateLocationException),
- create(toLocation(el.name, gl))
- )
- } yield result
- }
- //
- protected def create(location: Location): F[Location]
- protected def toLocation(name: String, gl: GoogleLocation): Location = {
- Location(UUID.randomUUID(), gl.placeId, name, normalize(name), gl.formattedAddress, gl.coordinates)
- }
- protected def normalize(s: String): String = {
- s.replaceAll("[^\\p{L}\\p{Nd}]+", "").toLowerCase
- }
- //
- protected implicit def ME: MonadError[F, LocationError]
- }
- sealed trait LocationError
- case object LocationNotFoundError extends LocationError
- case object InvalidLocationArgumentsError extends LocationError
- case object DuplicateLocationException extends LocationError
- case object RetryLaterError extends LocationError
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement