hotscript icon indicating copy to clipboard operation
hotscript copied to clipboard

Support regex patterns in `Strings.Replace`

Open gvergnaud opened this issue 2 years ago • 2 comments

Wouldn't it be nice if we could write things like Strings.Replace<'([A-Z]_?[a-z])|([a-z]_?[A-Z])', '&1-&2'>?

If somebody is up for a type challenge, here is a playground: Playground 😘

import {Pipe, S, T, Compose} from 'hotscript'

export type CamelCase<Str> = Pipe<
  Str,
  [
    S.Replace<"/([a-z])([A-Z])/g", "$1-$2">,
    S.Replace<"_", "-">,
    S.Split<"-">,
    T.Map<Compose<[S.Capitalize, S.Lowercase]>>,
    T.Join<"">,
    S.Uncapitalize
  ]
>;

type res1 = CamelCase<"ONE_two-three">;
//   ^?
type test1 = Expect<Equal<res1, "oneTwoThree">>;
type res2 = CamelCase<"one_TWO-three">;
//   ^?
type test2 = Expect<Equal<res2, "oneTwoThree">>;
type res3 = CamelCase<"one_two-THREE">;
//   ^?
type test3 = Expect<Equal<res3, "oneTwoThree">>;
type res4 = CamelCase<"ONE_TWO-THREE">;
//   ^?
type test4 = Expect<Equal<res4, "oneTwoThree">>;
type res5 = CamelCase<"alreadyInCamelCase">;
//   ^?
type test5 = Expect<Equal<res5, "alreadyInCamelCase">>;

gvergnaud avatar Feb 16 '23 17:02 gvergnaud

F.Compose was moved, here's an updated Playground

import {Pipe, Compose, S, T} from 'hotscript'

export type CamelCase<Str> = Pipe<Str, [
  // try replacing this
  S.Replace<'([A-Z]_?[a-z])|([a-z]_?[A-Z])', '&1-&2'>,
  // with:
  // S.Replace<'_', '-'>,
  S.Split<'-'>,
  T.Map<Compose<[S.Capitalize, S.Lowercase]>>,
  T.Join<''>,
  S.Uncapitalize
]>


type res1 = CamelCase<'ONE_two-three'>;
//   ^?
type test1 = Expect<Equal<res1, 'oneTwoThree'>>;
type res2 = CamelCase<'one_TWO-three'>;
//   ^?
type test2 = Expect<Equal<res2, 'oneTwoThree'>>;
type res3 = CamelCase<'one_two-THREE'>;
//   ^?
type test3 = Expect<Equal<res3, 'oneTwoThree'>>;
type res4 = CamelCase<'ONE_TWO-THREE'>;
//   ^?
type test4 = Expect<Equal<res4, 'oneTwoThree'>>;
type res5 = CamelCase<"alreadyInCamelCase">
//   ^?
type test5 = Expect<Equal<res5, 'alreadyInCamelCase'>>;




export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
    T,
>() => T extends Y ? 1 : 2
    ? true
    : false;

export type Expect<T extends true> = T;

franssu avatar Mar 24 '23 14:03 franssu

Hi @gvergnaud, @franssu I've made a PR #89 to implement this feature, did not include the example in this issue in the source code as I'm not sure here to put it, but you can copy and past the updated version below to test it out:

export type CamelCase<Str> = Pipe<
  Str,
  [
    S.Replace<"/([a-z]+)_(?<second>\\w+)/i", "$1-$<second>">,
    S.Split<"-">,
    T.Map<Compose<[S.Capitalize, S.Lowercase]>>,
    T.Join<"">,
    S.Uncapitalize,
    S.Match<"/(?<g1>[a-z]+)/i">,
    O.Get<"groups.g1">
  ]
>;

type res1 = CamelCase<"ONE_two-three">;
//   ^?
type test1 = Expect<Equal<res1, "oneTwoThree">>;
type res2 = CamelCase<"one_TWO-three">;
//   ^?
type test2 = Expect<Equal<res2, "oneTwoThree">>;
type res3 = CamelCase<"one_two-THREE">;
//   ^?
type test3 = Expect<Equal<res3, "oneTwoThree">>;
type res4 = CamelCase<"ONE_TWO-THREE">;
//   ^?
type test4 = Expect<Equal<res4, "oneTwoThree">>;
type res5 = CamelCase<"alreadyInCamelCase">;
//   ^?
type test5 = Expect<Equal<res5, "alreadyincamelcase">>;

And feedbacks or inputs are very welcome, thanks 😊

didavid61202 avatar Apr 17 '23 17:04 didavid61202