From aa9ef3c1aa1d30ad5eb8bb097c6ce24588564046 Mon Sep 17 00:00:00 2001 From: Baptiste Lyet Date: Thu, 29 Jan 2026 11:31:54 +0100 Subject: [PATCH] Feature : #27 Add utility to convert path segments to a FS2 Path --- .../src/main/scala/krop/route/Param.scala | 9 ++++++ .../main/scala/krop/tool/DefaultAssets.scala | 8 ++--- docs/src/pages/controller/route/paths.md | 29 +++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/core/shared/src/main/scala/krop/route/Param.scala b/core/shared/src/main/scala/krop/route/Param.scala index 37a3660..5e8a54f 100644 --- a/core/shared/src/main/scala/krop/route/Param.scala +++ b/core/shared/src/main/scala/krop/route/Param.scala @@ -16,6 +16,8 @@ package krop.route +import fs2.io.file.Path as Fs2Path + /** A [[package.Param]] is used to extract values from a URI's path or query * parameters. * @@ -104,6 +106,13 @@ object Param { val seq: Param.All[Seq[String]] = Param.All(SeqStringCodec.seqString) + /** `Param` that convert path segments to Fs2Path`. + */ + val fs2Path: Param[Fs2Path] = + Param + .separatedString("/") + .imap(Fs2Path.apply)(_.toString) + /** Constructs a [[Param]] that decodes input into a `String` by appending all * the input together with `separator` inbetween each element. Encodes data * by splitting on `separator`. diff --git a/core/shared/src/main/scala/krop/tool/DefaultAssets.scala b/core/shared/src/main/scala/krop/tool/DefaultAssets.scala index d09c18e..6387bde 100644 --- a/core/shared/src/main/scala/krop/tool/DefaultAssets.scala +++ b/core/shared/src/main/scala/krop/tool/DefaultAssets.scala @@ -18,7 +18,7 @@ package krop.tool import fs2.io.file.Path as Fs2Path import krop.route.Handler -import krop.route.Param +import krop.route.Param.fs2Path import krop.route.Path import krop.route.Request import krop.route.Response @@ -27,11 +27,7 @@ import krop.route.Route object DefaultAssets { val assets: Handler = Route( - Request.get( - Path / "assets" / Param - .separatedString("/") - .imap(Fs2Path.apply)(_.toString) - ), + Request.get(Path / "assets" / fs2Path), Response.staticDirectory(Fs2Path("assets/")) ).passthrough } diff --git a/docs/src/pages/controller/route/paths.md b/docs/src/pages/controller/route/paths.md index 7e1ac9c..64ff08b 100644 --- a/docs/src/pages/controller/route/paths.md +++ b/docs/src/pages/controller/route/paths.md @@ -201,3 +201,32 @@ intParam.name // Better, as the name has been changed appropriately. intParam.withName("").name ``` +### Convert path segments to a FS2 Path + +**fs2Path** utility in `Param` companion object is used to convert string path to a FS2 path +It supports bidirectional mapping: URL → Fs2Path and Fs2Path → URL. + +**Flow Diagram:** + +```` +Request URL: /assets/images/icons/logo.svg + │ + ▼ +Param.separatedString("/") → "images/icons/logo.svg" + │ + ▼ +Fs2Path.apply → Fs2Path("images/icons/logo.svg") + │ + ▼ +Route handler receives typed Fs2Path +```` + +**Usage in Route :** + +````scala + val staticDirectoryRoute = + Route( + Request.get(Path / "kroptest" / "assets" / AssetPath.fs2Path), + Response.StaticDirectory(Fs2Path("resources/kroptest/assets")) + ).passthrough +```` \ No newline at end of file