Skip to content

Instantly share code, notes, and snippets.

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 beccadax/2d644a3af52bd7ad631f2f2c164d6475 to your computer and use it in GitHub Desktop.
Save beccadax/2d644a3af52bd7ad631f2f2c164d6475 to your computer and use it in GitHub Desktop.
An implementation of a LocalizableString type in the Swift new-interpolation branch: https://github.com/brentdax/swift/tree/new-interpolation
import Foundation
public protocol LocalizableArgument {
var localizableFormat: String { get }
var localizableFormatArguments: [CVarArg] { get }
}
extension LocalizableArgument where Self: CVarArg {
public var localizableFormatArguments: [CVarArg] {
return [self]
}
}
extension String: LocalizableArgument {
public var localizableFormat: String {
return "%@"
}
public var localizableFormatArgument: CVarArg {
return self as NSString as CVarArg
}
}
public struct LocalizableString: LocalizableArgument {
public var localizableFormat: String
public var localizableFormatArguments: [CVarArg]
public func localizedFormat(inTable tableName: String? = nil, from bundle: Bundle = .main) -> String {
return bundle.localizedString(forKey: localizableFormat, value: nil, table: tableName)
}
public init(localizableFormat: String, arguments: [CVarArg]) {
self.localizableFormat = localizableFormat
self.localizableFormatArguments = arguments
}
public init(escaping plainText: String) {
let escapedScalars = plainText.unicodeScalars.flatMap { $0 == "%" ? [$0, $0] : [$0] }
self.init(localizableFormat: String(String.UnicodeScalarView(escapedScalars)), arguments: [])
}
public init(_ argument: LocalizableArgument) {
self.init(localizableFormat: argument.localizableFormat, arguments: argument.localizableFormatArguments)
}
}
public func localized(_ string: LocalizableString, comment: String = "", inTable tableName: String? = nil, from bundle: Bundle = .main) -> String {
let format = string.localizedFormat(inTable: tableName, from: bundle)
return String(format: format, locale: .current, arguments: string.localizableFormatArguments)
}
public func += (lhs: inout LocalizableString, rhs: LocalizableArgument) {
lhs.localizableFormat += rhs.localizableFormat
lhs.localizableFormatArguments += rhs.localizableFormatArguments
}
public func + (lhs: LocalizableArgument, rhs: LocalizableArgument) -> LocalizableString {
var copy = LocalizableString(lhs)
copy += rhs
return copy
}
extension LocalizableString: ExpressibleByStringInterpolation {
public init(stringLiteral value: String) {
self.init(escaping: value)
}
public init<T>(stringInterpolationSegment expr: T) {
if let expr = expr as? LocalizableArgument {
self.init(expr)
}
else {
self.init(String(describing: expr))
}
}
public init(stringInterpolation segments: LocalizableString...) {
self.init(escaping: "")
for segment in segments {
self += segment
}
}
public init(extendedGraphemeClusterLiteral value: String) {
self.init(stringLiteral: value)
}
public init(unicodeScalarLiteral value: String) {
self.init(extendedGraphemeClusterLiteral: value)
}
}
extension Int: LocalizableArgument {
public var localizableFormat: String { return "%d" }
}
extension Double: LocalizableArgument {
public var localizableFormat: String { return "%f" }
}
extension NSObject: LocalizableArgument {
public var localizableFormat: String { return "%@" }
}
print("Enter your name: ", terminator: "")
guard let name = readLine() else { print("Byeeeee"); exit(1) }
let s: LocalizableString = "Hello, \(name)!"
print(s.localizableFormat)
print(s.localizableFormatArguments)
print(localized("Hello, \(name)!"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment