You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
4.1 KiB

6 years ago
  1. // Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
  2. //
  3. // You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
  4. // copy, modify, and distribute this software in source code or binary form for use
  5. // in connection with the web services and APIs provided by Facebook.
  6. //
  7. // As with any software that integrates with the Facebook platform, your use of
  8. // this software is subject to the Facebook Developer Principles and Policies
  9. // [http://developers.facebook.com/policy/]. This copyright notice shall be
  10. // included in all copies or substantial portions of the software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  14. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  16. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  17. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. import Foundation
  19. /**
  20. Represents a type-safe OpenGraph property name.
  21. */
  22. public struct OpenGraphPropertyName {
  23. /// The namespace of this open graph property
  24. public var namespace: String
  25. /// The name of this open graph property
  26. public var name: String
  27. /**
  28. Attempt to parse an `OpenGraphPropertyName` from a raw OpenGraph formatted property name.
  29. - parameter string: The string to create from.
  30. */
  31. public init?(_ string: String) {
  32. let components = string.characters.split(separator: ":")
  33. guard components.count >= 2 else {
  34. return nil
  35. }
  36. self.namespace = String(components[0])
  37. let subcharacters = components[1 ... components.count]
  38. self.name = subcharacters.reduce("", { $0 + ":" + String($1) })
  39. }
  40. /**
  41. Create an `OpenGraphPropertyName` with a specific namespace and name.
  42. - parameter namespace: The namespace to use.
  43. - parameter name: The name to use.
  44. */
  45. public init(namespace: String, name: String) {
  46. self.namespace = namespace
  47. self.name = name
  48. }
  49. }
  50. extension OpenGraphPropertyName: RawRepresentable {
  51. public typealias RawValue = String
  52. /// The raw OpenGraph formatted property name.
  53. public var rawValue: String {
  54. return namespace.isEmpty
  55. ? name
  56. : namespace + ":" + name
  57. }
  58. /**
  59. Attempt to parse an `OpenGraphPropertyName` from a raw OpenGraph formatted proeprty name.
  60. - parameter rawValue: The string to create from.
  61. */
  62. public init(rawValue: String) {
  63. self.init(stringLiteral: rawValue)
  64. }
  65. }
  66. extension OpenGraphPropertyName: ExpressibleByStringLiteral {
  67. /**
  68. Create an `OpenGraphPropertyName` from a string literal.
  69. - parameter value: The string literal to create from.
  70. */
  71. public init(stringLiteral value: String) {
  72. guard let propertyName = OpenGraphPropertyName(value) else {
  73. print("Warning: Attempting to create OpenGraphPropertyName for string \"\(value)\", which has no namespace!")
  74. self.namespace = ""
  75. self.name = value
  76. return
  77. }
  78. self.namespace = propertyName.namespace
  79. self.name = propertyName.name
  80. }
  81. /**
  82. Create an `OpenGraphPropertyName` from a unicode scalar literal.
  83. - parameter value: The scalar literal to create from.
  84. */
  85. public init(unicodeScalarLiteral value: UnicodeScalarType) {
  86. self.init(stringLiteral: value)
  87. }
  88. /**
  89. Create an `OpenGraphPropertyName` from an grapheme cluster literal.
  90. - parameter value: The grapheme cluster to create from.
  91. */
  92. public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterType) {
  93. self.init(stringLiteral: value)
  94. }
  95. }
  96. extension OpenGraphPropertyName: Hashable {
  97. /// Calculates the hash value of this `OpenGraphPropertyName`.
  98. public var hashValue: Int {
  99. return rawValue.hashValue
  100. }
  101. /**
  102. Compares two `OpenGraphPropertyName`s for equality.
  103. - parameter lhs: The first property name to compare.
  104. - parameter rhs: The second property name to compare.
  105. - returns: Whether or not these names are equal.
  106. */
  107. public static func == (lhs: OpenGraphPropertyName, rhs: OpenGraphPropertyName) -> Bool {
  108. return lhs.rawValue == rhs.rawValue
  109. }
  110. }