Skip to content

JavierSegoviaCordoba/Resource

Repository files navigation

Master Download Coverage Master Master Build Quality Master
Develop Download Coverage Develop Develop Build Quality Develop

Resource

Resource is a sealed class that allows you to wrap any object based on a state. It has these options:

  • 🔄 Loading: To use at that moment that a loading indicator should appear.
  • 👍 Success: When the happy path occurs.
  • ❌ Error: If there is a problem you will get this.

This library works very well when used in conjunction with NetworkResponse which is very similar to Resource but is intended for use with Retrofit.

For more information see the website

Download

This library is Kotlin Multiplatform but at this moment jvm is the only artifact generated. It is available at Maven Central.

implementation("com.javiersc.resource:resource:$version")

Fold your Resource

Fold a Resource invokes multiple callbacks to manage its state for any event. A normal flow can be:

  1. Emit Loading to show the progress indicator.
  2. Emit Success to populate your data or emit Error if something were wrong to show an error.
val dog: Dog = Dog("Auri")
val resource: Resource<Dog, Error> = Resource.Success(dog)

resource.folder {
    loading { println("Loading: Yes") }
    noLoading { println("Loading: no") }  // Invoked

    success { dog: Dog -> println("Success: $dog") } // Invoked
    noSuccess { println("Success: no") }

    error { error: Error -> println("Error: $error") }
    noError { println("Error: no") }  // Invoked
}

Exists a fold function similar to folder buth without the builder pattern

val dog: Dog = Dog("Auri")
val resource: Resource<Dog, Error> = Resource.Success(dog)

resource.fold(
    loading = { println("Loading: Yes") },
    noLoading = { println("Loading: no") },  // Invoked
    success = { dog: Dog -> println("Success: $dog") }, // Invoked
    noSuccess = { println("Success: no") },
    error = { error: Error -> println("Error: $error") },
    noError = { println("Error: no") },  // Invoked
)

You don't have to add all those functions, for example, you usually only have to use:

  • loading to show a progress indicator.
  • noLoading to hide the progress indicator.
  • success to load the data.
  • error to show and error.

Mappers and common extension functions

Map a Resource to another Resource is possible with the following extension function:

  • Resource to Resource
val anotherResource: Resource<AnotherUser, AnotherError> = resource.map(
    success = { user: User -> user.toAnotherUser() },
    error = { error: Error -> error.toAnotherError() }
)
// toAnotherUser() and toAnotherError() mappers should be created by yourself, if they are
// extension functions and the resource uses inference for the type:
val anotherResource = resource.map(User::toAnotherUser, Error::toAnotherError)
  • Some value to Resource
val name: String = "Auri"
val nameResource = name.toResourceSuccess()

val message: String = "Some error message"
val messageResource = message.toResourceError()
  • A lot of checkers for each state, for example:
val resource: Resource<String> = Resource.Success("Auri")
resource.ifSuccess { data: String ->
    println(data) // "Auri"
}

You can see all the common extension functions here and here

Flow

There are four Flow extension functions:

  • Flow<R>.map(...) included in Kotlin, let you to easily map the object inside your Flow to any Resource:
val usersFlow: Flow<List<User>>

val usersResourceFlow: Flow<Resource<List<User>, Error>> =
    usersFlow.map { users: List<User> -> Resource.Success(users) }
  • Flow<R>.toResourceSuccess()
val usersSuccessFlow: Flow<Resource<List<User>, Error>> = usersFlow.toResourceSuccess()
  • Flow<R>.toResourceError()
val usersErrorFlow: Flow<Resource<List<User>, Error>> = usersFlow.toResourceError()

About

Resource is a sealed class that allows you to wrap any object based on a state.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages