-
Notifications
You must be signed in to change notification settings - Fork 472
Add FieldMask utilities to Message types #1505
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
c889293
Add applying and tests
pouyayarandi f01f29c
Move extension to another file
eaa0666
Some minor changes in comments
9e33a9b
Revert "Some minor changes in comments"
b728a33
Revert "Move extension to another file"
634ca09
Revert "Add applying and tests"
ad59804
Implement field mask utils
1b5fbe9
Update cmakelist
c1e42b2
Add comments for path decoding error
da24d19
Change APIs
1c94065
Add comments
af441d1
Remove copy mechanism in some functions
249b066
Change path contain and canonical algorithm
795b22a
Rename field mask error
095dde2
Fix intersect and subtract
37f1872
Implement merge option
08270b5
Add comments
d657a81
Fix bug of extra paths
pouyayarandi 3269433
Fix comment
pouyayarandi d564895
Change if to guard
pouyayarandi fcec7f2
Fix comments
787957f
Fix variable names with underscore
eedb785
Fix comments
d7ba532
Fix comments
03f5f0d
Fix build errors in swift 5.8 and later using any keyword for type-ca…
9e15359
Add a test for trim with extensible messages
dcfa442
Rename merge(from:) to merge(with:)
aae790b
Replace GetPathDecoder with PathVisitor
db6be11
Improve tests
1ef69c9
Fix comments
35163e1
Fix failing test
702679b
Fix issue of json path names
e3d01ea
Fix comments
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
// Sources/SwiftProtobuf/Message+FieldMask.swift - Message field mask extensions | ||
// | ||
// Copyright (c) 2014 - 2023 Apple Inc. and the project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See LICENSE.txt for license information: | ||
// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt | ||
// | ||
// ----------------------------------------------------------------------------- | ||
/// | ||
/// Extend the Message types with FieldMask utilities. | ||
/// | ||
// ----------------------------------------------------------------------------- | ||
|
||
import Foundation | ||
|
||
extension Message { | ||
|
||
/// Checks whether the given path is valid for Message type. | ||
/// | ||
/// - Parameter path: Path to be checked | ||
/// - Returns: Boolean determines path is valid. | ||
public static func isPathValid( | ||
_ path: String | ||
) -> Bool { | ||
var message = Self() | ||
return message.hasPath(path: path) | ||
} | ||
|
||
internal mutating func hasPath(path: String) -> Bool { | ||
do { | ||
try set(path: path, value: nil, mergeOption: .init()) | ||
return true | ||
} catch let error as PathDecodingError { | ||
return error != .pathNotFound | ||
} catch { | ||
return false | ||
} | ||
} | ||
|
||
internal mutating func isPathValid( | ||
thomasvl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
_ path: String | ||
) -> Bool { | ||
hasPath(path: path) | ||
} | ||
} | ||
|
||
extension Google_Protobuf_FieldMask { | ||
|
||
/// Defines available options for merging two messages. | ||
public struct MergeOptions { | ||
|
||
public init() {} | ||
|
||
/// The default merging behavior will append entries from the source | ||
/// repeated field to the destination repeated field. If you only want | ||
/// to keep the entries from the source repeated field, set this flag | ||
/// to true. | ||
public var replaceRepeatedFields = false | ||
} | ||
} | ||
|
||
extension Message { | ||
|
||
/// Merges fields specified in a FieldMask into another message. | ||
/// | ||
/// - Parameters: | ||
/// - source: Message that should be merged to the original one. | ||
/// - fieldMask: FieldMask specifies which fields should be merged. | ||
public mutating func merge( | ||
from source: Self, | ||
fieldMask: Google_Protobuf_FieldMask, | ||
mergeOption: Google_Protobuf_FieldMask.MergeOptions = .init() | ||
) throws { | ||
var visitor = PathVisitor<Self>() | ||
try source.traverse(visitor: &visitor) | ||
let values = visitor.values | ||
// TODO: setting all values with only one decoding | ||
for path in fieldMask.paths { | ||
thomasvl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
try? set( | ||
path: path, | ||
value: values[path], | ||
mergeOption: mergeOption | ||
) | ||
} | ||
} | ||
} | ||
|
||
extension Message where Self: Equatable, Self: _ProtoNameProviding { | ||
|
||
// TODO: Re-implement using clear fields instead of copying message | ||
|
||
/// Removes from 'message' any field that is not represented in the given | ||
/// FieldMask. If the FieldMask is empty, does nothing. | ||
/// | ||
/// - Parameter fieldMask: FieldMask specifies which fields should be kept. | ||
/// - Returns: Boolean determines if the message is modified | ||
@discardableResult | ||
public mutating func trim( | ||
keeping fieldMask: Google_Protobuf_FieldMask | ||
) -> Bool { | ||
if !fieldMask.isValid(for: Self.self) { | ||
return false | ||
} | ||
if fieldMask.paths.isEmpty { | ||
return false | ||
} | ||
var tmp = Self(removingAllFieldsOf: self) | ||
do { | ||
try tmp.merge(from: self, fieldMask: fieldMask) | ||
let changed = tmp != self | ||
self = tmp | ||
thomasvl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return changed | ||
} catch { | ||
return false | ||
} | ||
} | ||
} | ||
|
||
private extension Message { | ||
init(removingAllFieldsOf message: Self) { | ||
let newMessage: Self = .init() | ||
if var newExtensible = newMessage as? any ExtensibleMessage, | ||
let extensible = message as? any ExtensibleMessage { | ||
newExtensible._protobuf_extensionFieldValues = extensible._protobuf_extensionFieldValues | ||
self = newExtensible as? Self ?? newMessage | ||
} else { | ||
self = newMessage | ||
} | ||
self.unknownFields = message.unknownFields | ||
} | ||
} |
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.