// // Attribute.swift // QueryKit // // Created by Kyle Fuller on 19/06/2014. // // import Foundation public struct Attribute : Equatable { public let name:String public init(_ name:String) { self.name = name } /// Builds a compound attribute with other key paths public init(attributes:Array) { self.init(".".join(attributes)) } public var expression:NSExpression { return NSExpression(forKeyPath: name) } // MARK: Sorting public func ascending() -> NSSortDescriptor { return NSSortDescriptor(key: name, ascending: true) } public func descending() -> NSSortDescriptor { return NSSortDescriptor(key: name, ascending: false) } func expressionForValue(value:T) -> NSExpression { if let value = value as? NSObject { return NSExpression(forConstantValue: value as NSObject) } if sizeof(value.dynamicType) == 8 { let value = unsafeBitCast(value, Optional.self) if let value = value { return NSExpression(forConstantValue: value) } } let value = unsafeBitCast(value, Optional.self) if let value = value { return NSExpression(forConstantValue: value) } return NSExpression(forConstantValue: NSNull()) } } public func == (lhs: Attribute, rhs: Attribute) -> Bool { return lhs.name == rhs.name } public func == (left: Attribute, right: T) -> NSPredicate { return left.expression == left.expressionForValue(right) } public func != (left: Attribute, right: T) -> NSPredicate { return left.expression != left.expressionForValue(right) } public func > (left: Attribute, right: T) -> NSPredicate { return left.expression > left.expressionForValue(right) } public func >= (left: Attribute, right: T) -> NSPredicate { return left.expression >= left.expressionForValue(right) } public func < (left: Attribute, right: T) -> NSPredicate { return left.expression < left.expressionForValue(right) } public func <= (left: Attribute, right: T) -> NSPredicate { return left.expression <= left.expressionForValue(right) } public func ~= (left: Attribute, right: T) -> NSPredicate { return left.expression ~= left.expressionForValue(right) } public func << (left: Attribute, right: [T]) -> NSPredicate { return left.expression << NSExpression(forConstantValue: right._asCocoaArray()) } public func << (left: Attribute, right: Range) -> NSPredicate { let rightExpression = NSExpression(forConstantValue: [right.startIndex, right.endIndex]._asCocoaArray()) return NSComparisonPredicate(leftExpression: left.expression, rightExpression: rightExpression, modifier: NSComparisonPredicateModifier.DirectPredicateModifier, type: NSPredicateOperatorType.BetweenPredicateOperatorType, options: NSComparisonPredicateOptions(0)) } /// MARK: Bool Attributes prefix public func ! (left: Attribute) -> NSPredicate { return left == false } public extension QuerySet { public func filter(attribute:Attribute) -> QuerySet { return filter(attribute == true) } public func exclude(attribute:Attribute) -> QuerySet { return filter(attribute == false) } } // MARK: Collections public func count(attribute:Attribute) -> Attribute { return Attribute(attributes: [attribute.name, "@count"]) } public func count(attribute:Attribute) -> Attribute { return Attribute(attributes: [attribute.name, "@count"]) }