* fix(conversion): keep an absent UpdateResult.operation_id as None over gRPC
`UpdateResult.operation_id` is declared `optional uint64` in points.proto, so
it carries explicit presence. The server leaves it unset for updates that were
never assigned a sequence number - a delete-by-filter that matched no points, a
clock-rejected update, or a write to a custom-sharded collection that has no
shard keys yet.
`GrpcToRest.convert_update_result` read the field unconditionally, so the proto
default surfaced as `operation_id=0` while the same update over REST (where the
key is omitted from the body) yields `operation_id=None`. Since 0 is also a
valid operation id, callers could not tell the two apart.
Guard the read with `HasField`, matching the presence handling already used for
the neighbouring optional fields in this module.
* fix(conversion): keep an absent CollectionInfo.points_count as None over gRPC
`points_count` is `optional uint64` in collections.proto, so it carries explicit presence and the server may leave it unset when the count is not available. `GrpcToRest.convert_collection_info` read it unconditionally, so `get_collection` over gRPC reported `points_count=0` where the REST client reports `None`, turning "count unavailable" into "collection is empty". The sibling `indexed_vectors_count` on the next line is already guarded with `HasField`. Guard `points_count` the same way.
* tests: extend tests
---------
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
grpc.KeywordPrefixParams is an empty message: presence is the only
signal, so an explicit prefix=False cannot be represented in gRPC.
It is sent as absent (same server-side semantics, disabled) and is
recovered as None. Document this at both conversion sites and pin
the behavior with a reverse-direction (rest->grpc->rest) test.