Files
SwiftMail/Sources/SwiftIMAP/IMAP/Commands/SearchCommand.swift
Oliver Drobnik ce58c2a1b8 Implement SORT command in IMAP
Related to #11

Implement the `SORT` command to allow clients to search and sort messages on the server.

* **SearchCommand.swift**
  - Update `SearchCommand` to accept sort criteria as an optional parameter.
  - Modify `toTaggedCommand` method to handle sort criteria.

* **IMAPServer.swift**
  - Add sort criteria parameter to the existing `search` function.
  - Add capability check for `SORT` before executing `SearchCommand`.
  - Implement fallback to `SEARCH` if `SORT` is not supported.

* **SearchHandler.swift**
  - Update `SearchHandler` to handle responses for both `SEARCH` and `SORT` commands.
  - Modify error handling to include `SORT` command failures.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/Cocoanetics/SwiftMail/issues/11?shareId=XXXX-XXXX-XXXX-XXXX).
2025-03-12 15:05:30 +01:00

50 lines
1.9 KiB
Swift

import Foundation
import NIO
import NIOIMAP
import NIOIMAPCore
public struct SearchCommand<T: MessageIdentifier>: IMAPCommand {
// Update the result type to return a MessageIdentifierSet
public typealias ResultType = MessageIdentifierSet<T>
public typealias HandlerType = SearchHandler<T>
public let identifierSet: MessageIdentifierSet<T>?
public let criteria: [SearchCriteria]
public let sortCriteria: [SortCriteria]?
public var handlerType: HandlerType.Type { SearchHandler<T>.self }
public var timeoutSeconds: Int { return 10 }
public init(identifierSet: MessageIdentifierSet<T>? = nil, criteria: [SearchCriteria], sortCriteria: [SortCriteria]? = nil) {
self.identifierSet = identifierSet
self.criteria = criteria
self.sortCriteria = sortCriteria
}
public func validate() throws {
guard !criteria.isEmpty else {
throw IMAPError.invalidArgument("Search criteria cannot be empty")
}
}
public func toTaggedCommand(tag: String) -> TaggedCommand {
let nioCriteria = criteria.map { $0.toNIO() }
if let sortCriteria = sortCriteria, !sortCriteria.isEmpty {
let nioSortCriteria = sortCriteria.map { $0.toNIO() }
if T.self == UID.self {
return TaggedCommand(tag: tag, command: .uidSort(sort: nioSortCriteria, charset: "UTF-8", searchKey: .and(nioCriteria)))
} else {
return TaggedCommand(tag: tag, command: .sort(sort: nioSortCriteria, charset: "UTF-8", searchKey: .and(nioCriteria)))
}
} else {
if T.self == UID.self {
return TaggedCommand(tag: tag, command: .uidSearch(key: .and(nioCriteria)))
} else {
return TaggedCommand(tag: tag, command: .search(key: .and(nioCriteria)))
}
}
}
}