Last active
August 29, 2015 14:04
-
-
Save seanlilmateus/8dc345d035a020f793f4 to your computer and use it in GitHub Desktop.
FromStr Protocol the power of Swift Type System...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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