ruxo
8/9/2015 - 4:32 AM

String Extensions

String Extensions

module RZ.String

/// <summary>
/// Case-insensitive string
/// </summary>
type iString(s: string) =
  let normalized = s.ToLower(Globalization.CultureInfo.InvariantCulture)
  let ieq a b = System.String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
  let icmp a b = System.String.Compare(s, b, StringComparison.OrdinalIgnoreCase)

  let eval def f (a: obj) =
    match a with
    | :? string as a_str -> f s a_str
    | :? iString as other -> f s other.Value
    | _ -> def()

  member x.Value = s

  override x.Equals(a) = eval (fun _ -> false) ieq a

  override x.GetHashCode() = normalized.GetHashCode()

  override x.ToString() = s

  interface IComparable with
    member x.CompareTo(a) = eval (fun _ -> raise <| ArgumentException(a.GetType().ToString())) icmp a

  member x.StartsWith other = s.StartsWith(other, StringComparison.OrdinalIgnoreCase)
  member x.Substring(start) = iString <| s.Substring(start)
  member x.IfBlank(new_s) = if String.IsNullOrEmpty s then iString new_s else x
  member x.map(f) = iString (f s)

  static member get (s: iString) = s.Value


[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module iString =
  let map f (s: iString) = s.map(f)
using System;

namespace RZ.Extensions{
    public class NotNullableString : IComparable, IComparable<NotNullableString> {
        readonly string s;
        public NotNullableString(string s){
            if (s == null)
                throw new InvalidOperationException("String cannot be null!");
            this.s = s;
        }
        public override string ToString(){
            return s;
        }
        public override bool Equals(object o) {
            var anotherNS = o as NotNullableString;
            if (anotherNS != null)
                return anotherNS.s == s;
            else {
                var anotherS = o as string;
                return (anotherS != null) && anotherS == s;
            }
        }
        public override int GetHashCode() {
            return s.GetHashCode();
        }
        public int CompareTo(object obj){
            return s.CompareTo(obj);
        }

        public int CompareTo(NotNullableString other){
            return other.s.CompareTo(s);
        }

        static public implicit operator String(NotNullableString ns){
            return ns.s;
        }
        static public implicit operator NotNullableString(string s){
            return new NotNullableString(s);
        }
    }
    public static class StringExtension{
        static public string Apply<T>(this string s, T data){
            return String.Format(s, data);
        }
        static public string Apply<T, U>(this string s, T data, U o2) {
            return String.Format(s, data, o2);
        }
        static public string Apply<T, U, V>(this string s, T data, U o2, V o3) {
            return String.Format(s, data, o2, o3);
        }
    }
}
module RZ.String

/// <summary>
/// New Non-blank string
/// </summary>
type NBString = NBString of string
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module NBString =
    let from s =
        if String.IsNullOrWhiteSpace s then invalidArg "s" "String cannot be blank or empty"
        NBString s
    let get (NBString s) = s