Skip to content

Instantly share code, notes, and snippets.

@seanlilmateus
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seanlilmateus/8dc345d035a020f793f4 to your computer and use it in GitHub Desktop.
Save seanlilmateus/8dc345d035a020f793f4 to your computer and use it in GitHub Desktop.
FromStr Protocol the power of Swift Type System...
#!/usr/bin/env xcrun swift -i
import Foundation
// MARK: From String Protocol
protocol FromStr {
class func fromStr(value: String) -> Self?
}
extension Bool : FromStr {
static func fromStr(str: String) -> Bool? {
switch str {
case "true": return .Some(true)
case "false": return .Some(false)
default: return .None
}
}
}
extension String : FromStr {
static func fromStr(str: String) -> String? {
return .Some(str)
}
}
extension UInt8 : FromStr {
static func fromStr(str: String) -> UInt8? {
if let value = str.toInt() {
if value >= Int(UInt8.min) && value <= Int(UInt8.max) {
return UInt8(value)
}
return Optional<UInt8>.None
} else {
return .None
}
}
}
extension Int8 : FromStr {
static func fromStr(str: String) -> Int8? {
if let value = str.toInt() {
if value >= Int(Int8.min) && value <= Int(Int8.max) {
return Int8(value)
}
return Optional<Int8>.None
} else {
return .None
}
}
}
extension UInt16 : FromStr {
static func fromStr(str: String) -> UInt16? {
if let value = str.toInt() {
if value >= Int(UInt16.min) && value <= Int(UInt16.max) {
return UInt16(value)
}
return Optional<UInt16>.None
} else {
return .None
}
}
}
extension Int16 : FromStr {
static func fromStr(str: String) -> Int16? {
if let value = str.toInt() {
if value >= Int(Int16.min) && value <= Int(Int16.max) {
return Int16(value)
}
return Optional<Int16>.None
} else {
return .None
}
}
}
extension UInt32 : FromStr {
static func fromStr(str: String) -> UInt32? {
if let value = str.toInt() {
if value >= Int(UInt32.min) && value <= Int(UInt32.max) {
return UInt32(value)
}
return Optional<UInt32>.None
} else {
return .None
}
}
}
extension Int32 : FromStr {
static func fromStr(str: String) -> Int32? {
if let value = str.toInt() {
if value >= Int(Int32.min) && value <= Int(Int32.max) {
return Int32(value)
}
return Optional<Int32>.None
} else {
return .None
}
}
}
// From here it's a little Buggy...
// Since we're using String#toInt(), the Max value will be :: 9223372036854775807 ::
// We need a way to create UInt64 from String... I haven't found it yet.
extension UInt64 : FromStr {
static func fromStr(str: String) -> UInt64? {
if let value = str.toInt() {
if UInt64(value) >= UInt64.min && UInt64(value) <= UInt64.max {
return UInt64(value)
}
return Optional<UInt64>.None
} else {
return .None
}
}
}
extension Int64 : FromStr {
static func fromStr(str: String) -> Int64? {
if let value = str.toInt() {
if Int64(value) >= Int64.min && Int64(value) <= Int64.max {
return Int64(value)
}
return Optional<Int64>.None
} else {
return .None
}
}
}
extension UInt : FromStr {
static func fromStr(str: String) -> UInt? {
if let value = str.toInt() {
if UInt(value) >= UInt.min && UInt(value) <= UInt.max {
return UInt(value)
}
return Optional<UInt>.None
} else {
return .None
}
}
}
extension Int : FromStr {
static func fromStr(str: String) -> Int? {
return str.toInt()
}
}
// NSDate
extension NSDate : FromStr {
class func fromStr(str: String) -> NSDate? {
if let date = NSDate.dateWithNaturalLanguageString(str) as? NSDate {
return Optional<NSDate>.Some(date)
} else {
return Optional<NSDate>.None
}
}
}
// Utility Function, creates anything that implements `FromStr` protocol
func fromStr<T: FromStr>(str: String) -> T? {
return .fromStr(str)
}
let valid:Bool? = fromStr("false")
println(valid) // => Optional(false)
let uint8:UInt8? = fromStr("10")
if let num = uint8 { println(num) } // => 10
let uint32:UInt32? = fromStr("10000")
if let num = uint32 { println(num) } // => 10000
// MARK: failing example
let uint64:UInt64? = fromStr("18446744073709551615")
if let num = uint64 { println(num) } else { println("FAILED") } // FAILED
// NSDate
let today:NSDate? = fromStr("Today")
println(today) // => Optional(2014-08-02 12:00:00 +0200)
let date:NSDate? = fromStr("2011-08-12T12:20:00Z")
println(date) // => Optional(2011-08-12 12:20:00 +0000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment