Skip to content

Commit

Permalink
[Rust] Added Char surrogate tests for completeness (#3939)
Browse files Browse the repository at this point in the history
  • Loading branch information
ncave authored Oct 25, 2024
1 parent 5355b7c commit f6f33a6
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 93 deletions.
1 change: 1 addition & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [Rust] Support type extensions for external types (by @ncave)
* [Rust] Support more System.Array methods and tests (by @ncave)
* [Rust] Added decision tree multiple target references (by @ncave)
* [Rust] Added Char surrogate tests for completeness (by @ncave)
* [JS] Add `System.String.Normalize` support (by @DashieTM)

### Fixed
Expand Down
28 changes: 14 additions & 14 deletions src/Fable.Transforms/Rust/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,11 +1163,10 @@ let operators (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr o
| _ -> None

let chars (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
let getMethod meth args =
if List.length args > 1 then
meth + "_2"
else
meth
let getMethodName meth args =
match args with
| (ExprType String) :: _ -> meth + "_2"
| _ -> meth

match i.CompiledName, thisArg, args with
| ("IsBetween" as meth), None, _ ->
Expand All @@ -1178,15 +1177,15 @@ let chars (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr optio
[ c ] ->
Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc = r)
|> Some
| ("IsControl" | "IsDigit" | "IsLetter" | "IsLetterOrDigit" | "IsLower" | "IsUpper" | "IsNumber" | "IsPunctuation" | "IsSeparator" | "IsSurrogate" | "IsSymbol" | "IsWhiteSpace" as meth),
| ("IsControl" | "IsDigit" | "IsLetter" | "IsLetterOrDigit" | "IsLower" | "IsUpper" | "IsNumber" | "IsPunctuation" | "IsSeparator" | "IsSymbol" | "IsWhiteSpace" as meth),
None,
_ ->
let meth = getMethod meth args
let meth = getMethodName meth args

Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc = r)
|> Some
| ("GetNumericValue" | "GetUnicodeCategory" | "ConvertToUtf32" as meth), None, _ ->
let meth = getMethod meth args
let meth = getMethodName meth args

Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc = r)
|> Some
Expand All @@ -1198,13 +1197,14 @@ let chars (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr optio
| ("TryParse" | "Parse" as meth), None, _ ->
Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc = r)
|> Some
| ("IsSurrogate" | "IsHighSurrogate" | "IsLowSurrogate" | "IsSurrogatePair" as meth), None, _ ->
$"Rust chars are Unicode scalar values, so surrogate tests will be false."
|> addWarning com ctx.InlinePath r

// | ("IsHighSurrogate" | "IsLowSurrogate" as meth), None, _ ->
// let meth = getMethod meth args
// Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
// | ("IsSurrogatePair" as meth), None, _ ->
// let meth = if args.Head.Type = String then meth + "_2" else meth
// Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
let meth = getMethodName meth args

Helper.LibCall(com, "Char", meth, t, args, i.SignatureArgTypes, ?loc = r)
|> Some
| _ -> None

let getEnumerator com r t i (expr: Expr) =
Expand Down
75 changes: 39 additions & 36 deletions src/fable-library-rust/src/Char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,6 @@ pub mod Char_ {
}
}

pub fn IsSurrogate(c: char) -> bool {
// c as u32 >= 0xD800 && c as u32 <= 0xDFFF
c.len_utf16() > 1
}

pub fn IsSymbol(c: char) -> bool {
// isUnicodeCategory(c, isSymbolMask)
c.is_ascii_punctuation() //TODO: imprecise, fix this
Expand Down Expand Up @@ -398,11 +393,6 @@ pub mod Char_ {
IsSeparator(c)
}

pub fn IsSurrogate_2(s: string, index: i32) -> bool {
let c: char = getCharAt(s, index);
IsSurrogate(c)
}

pub fn IsSymbol_2(s: string, index: i32) -> bool {
let c: char = getCharAt(s, index);
IsSymbol(c)
Expand Down Expand Up @@ -441,35 +431,48 @@ pub mod Char_ {
ToLower(c) //TODO: use invariant culture
}

// pub fn IsHighSurrogate(c: char) -> bool {
// c as u32 >= 0xD800 && c as u32 <= 0xDBFF
// }
// ----------------------------------------------------
// Rust chars are Unicode scalar values, so surrogate tests will be false
// ----------------------------------------------------

// pub fn IsHighSurrogate_2(s: string, index: i32) -> bool {
// let c: char = getCharAt(s, index);
// IsHighSurrogate(c)
// }
pub fn IsSurrogate(c: char) -> bool {
c as u32 >= 0xD800 && c as u32 <= 0xDFFF
}

// pub fn IsLowSurrogate(c: char) -> bool {
// c as u32 >= 0xDC00 && c as u32 <= 0xDFFF
// }
pub fn IsSurrogate_2(s: string, index: i32) -> bool {
let c: char = getCharAt(s, index);
IsSurrogate(c)
}

// pub fn IsLowSurrogate_2(s: string, index: i32) -> bool {
// let c: char = getCharAt(s, index);
// IsLowSurrogate(c)
// }
pub fn IsHighSurrogate(c: char) -> bool {
c as u32 >= 0xD800 && c as u32 <= 0xDBFF
}

// pub fn IsSurrogatePair(c1: char, c2: char) -> bool {
// IsHighSurrogate(c1) && IsLowSurrogate(c2)
// }
pub fn IsHighSurrogate_2(s: string, index: i32) -> bool {
let c: char = getCharAt(s, index);
IsHighSurrogate(c)
}

// pub fn IsSurrogatePair_2(s: string, index: i32) -> bool {
// let c1: char = getCharAt(s.clone(), index);
// if (index + 1 < length(s.clone())) {
// let c2: char = getCharAt(s.clone(), index + 1);
// IsSurrogatePair(c1, c2)
// } else {
// false
// }
// }
pub fn IsLowSurrogate(c: char) -> bool {
c as u32 >= 0xDC00 && c as u32 <= 0xDFFF
}

pub fn IsLowSurrogate_2(s: string, index: i32) -> bool {
let c: char = getCharAt(s, index);
IsLowSurrogate(c)
}

pub fn IsSurrogatePair(c1: char, c2: char) -> bool {
IsHighSurrogate(c1) && IsLowSurrogate(c2)
}

pub fn IsSurrogatePair_2(s: string, index: i32) -> bool {
let c1: char = getCharAt(s.clone(), index);
if (index + 1 < length(s.clone())) {
let c2: char = getCharAt(s.clone(), index + 1);
IsSurrogatePair(c1, c2)
} else {
false
}
}
}
86 changes: 43 additions & 43 deletions tests/Rust/tests/src/CharTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -177,56 +177,56 @@ let ``Char.IsWhitespace works with two args`` () =
Char.IsWhiteSpace(input, 0) |> equal true
Char.IsWhiteSpace(input, 1) |> equal true

// [<Fact>]
// let ``Char.IsHighSurrogate works`` () =
// Char.IsHighSurrogate('a') |> equal false
// Char.IsHighSurrogate("\U00010F00"[0]) |> equal true
[<Fact>]
let ``Char.IsHighSurrogate works`` () =
Char.IsHighSurrogate('a') |> equal false
// Char.IsHighSurrogate("\U00010F00"[0]) |> equal true

// [<Fact>]
// let ``Char.IsHighSurrogate with two args works`` () =
// let str = "a\U00010F00z"
// Char.IsHighSurrogate(str,0) |> equal false
// Char.IsHighSurrogate(str,1) |> equal true
// Char.IsHighSurrogate(str,2) |> equal false
// Char.IsHighSurrogate(str,3) |> equal false
[<Fact>]
let ``Char.IsHighSurrogate with two args works`` () =
let str = "a\U00010F00z"
Char.IsHighSurrogate(str,0) |> equal false
// Char.IsHighSurrogate(str,1) |> equal true
// Char.IsHighSurrogate(str,2) |> equal false
// Char.IsHighSurrogate(str,3) |> equal false

// [<Fact>]
// let ``Char.IsLowSurrogate works`` () =
// Char.IsLowSurrogate('a') |> equal false
// Char.IsLowSurrogate("\U00010F00"[1]) |> equal true
[<Fact>]
let ``Char.IsLowSurrogate works`` () =
Char.IsLowSurrogate('a') |> equal false
// Char.IsLowSurrogate("\U00010F00"[1]) |> equal true

// [<Fact>]
// let ``Char.IsLowSurrogate with two args works`` () =
// let str = "a\U00010F00z"
// Char.IsLowSurrogate(str,0) |> equal false
// Char.IsLowSurrogate(str,1) |> equal false
// Char.IsLowSurrogate(str,2) |> equal true
// Char.IsLowSurrogate(str,3) |> equal false
[<Fact>]
let ``Char.IsLowSurrogate with two args works`` () =
let str = "a\U00010F00z"
Char.IsLowSurrogate(str,0) |> equal false
// Char.IsLowSurrogate(str,1) |> equal false
// Char.IsLowSurrogate(str,2) |> equal true
// Char.IsLowSurrogate(str,3) |> equal false

// [<Fact>]
// let ``Char.IsSurrogate works`` () =
// Char.IsSurrogate('a') |> equal false
// Char.IsSurrogate("\U00010F00"[1]) |> equal true
[<Fact>]
let ``Char.IsSurrogate works`` () =
Char.IsSurrogate('a') |> equal false
// Char.IsSurrogate("\U00010F00"[1]) |> equal true

// [<Fact>]
// let ``Char.IsSurrogate with two args works`` () =
// let str = "a\U00010F00z"
// Char.IsSurrogate(str,0) |> equal false
// Char.IsSurrogate(str,1) |> equal true
// Char.IsSurrogate(str,2) |> equal true
// Char.IsSurrogate(str,3) |> equal false
[<Fact>]
let ``Char.IsSurrogate with two args works`` () =
let str = "a\U00010F00z"
Char.IsSurrogate(str,0) |> equal false
// Char.IsSurrogate(str,1) |> equal true
// Char.IsSurrogate(str,2) |> equal true
// Char.IsSurrogate(str,3) |> equal false

// [<Fact>]
// let ``Char.IsSurrogatePair works`` () =
// Char.IsSurrogatePair('a', 'b') |> equal false
// Char.IsSurrogatePair("\U00010F00"[0], "\U00010F00"[1]) |> equal true
[<Fact>]
let ``Char.IsSurrogatePair works`` () =
Char.IsSurrogatePair('a', 'b') |> equal false
// Char.IsSurrogatePair("\U00010F00"[0], "\U00010F00"[1]) |> equal true

// [<Fact>]
// let ``Char.IsSurrogatePair with two args works`` () =
// let str = "a\U00010F00z"
// Char.IsSurrogatePair(str,0) |> equal false
// Char.IsSurrogatePair(str,1) |> equal true
// Char.IsSurrogatePair(str,2) |> equal false
[<Fact>]
let ``Char.IsSurrogatePair with two args works`` () =
let str = "a\U00010F00z"
Char.IsSurrogatePair(str,0) |> equal false
// Char.IsSurrogatePair(str,1) |> equal true
// Char.IsSurrogatePair(str,2) |> equal false

[<Fact>]
let ``Char.Parse works`` () =
Expand Down

0 comments on commit f6f33a6

Please sign in to comment.