2

So, using Foundation you can use NSCharacterSet to define character sets and test character membership in Strings. I would like to do so without Cocoa classes, but in a purely Swift manner.

Ideally, code could be used like so:

struct ReservedCharacters: CharacterSet {
    characters "!", "#", "$", "&", ... etc.

    func isMember(character: Character) -> Bool

    func encodeCharacter(parameters) { accepts a closure }

    func decodeCharacter(parameters) { accepts a closure }
}

This is probably a very loaded question. But I'd like to see what you Swifters think.

Sean
  • 377
  • 3
  • 12

1 Answers1

2

You can already test for membership in a character set by initializing a String and using the contains global function:

let vowels = "aeiou"

let isVowel = contains(vowels, "i") // isVowel == true

As far as your encode and decode functions go, are you just trying to get the 8-bit or 16-bit encodings for the Character? If that is the case then just convert them to a String and access there utf8 or utf16 properties:

let char = Character("c")

let a = Array(String(char).utf8)
println()          // This prints [99]

Decode would take a little more work, but I know there's a function for it...

Edit: This will replace a character from a characterSet with '%' followed by the character's hex value:

let encode: String -> String = { s in
    reduce(String(s).unicodeScalars, "") { x, y in
        switch contains(charSet, Character(y)) {
        case true:
            return x + "%" + String(y.value, radix: 16)
        default:
            return x + String(y)
        }
    }
}

let badURL = "http://why won't this work.com"
let encoded = encode(badURL)
println(encoded)   // prints "http://why%20won%27t%20this%20work.com"

Decoding, again, is a bit more challenging, but I'm sure it can be done...

Aaron Rasmussen
  • 13,082
  • 3
  • 42
  • 43
  • So the application of this would be in a URL/URI encoding. The contains( ) function would work fine for isMember but for "translating" or encoding a string with percent encoding particular characters in a string need to be changed. For example, "!" -> "%21". Using a character set would be handy because membership may be tested by just defining particular characters in the set and encoding may be done via a closure or external function. – Sean Jan 28 '15 at 03:31
  • This is a great implementation! I was hoping for a way to test membership in a way that isn't a string of just characters but it'll do. I can find a way to give that wrapper that if I need to. – Sean Jan 29 '15 at 21:22
  • As for decoding, I would use a delimit( ) function that've written to separate the strings in the URL/URI depending based on symbols and hex lookup... BUT practically speaking, is there any real need/use for decoding a URI/URL? – Sean Jan 29 '15 at 21:24
  • You can test for membership in an NSCharacterSet, (i.e., lowercase set, symbol set, etc.), but it is more complicated because Swift characters can be composed of more than one unicode code point. I actually delved fairly deep into this at one point and wrote a blog post about it. http://letvargo.mooo.com/the-swift-character-type-part-3/ – Aaron Rasmussen Jan 29 '15 at 23:54
  • Yes this is true. That's a great blog post! Unfortunately, the whole goal of this is to be Purely Swift—no Foundation nor Cocoa classes. Anything with a NeXTSTEP prefix is a non-starter. My project is to build a pure Swift replacement for Cocoa. – Sean Jan 30 '15 at 03:08
  • Or you know, just wait for Apple to replace Cocoa? – user965972 Oct 16 '15 at 07:40