Advanced Usage
Global registry of structs and interfaces.
Adding an annotation to a struct or interface will add it to a registry in cara with all their IDs. This allows the benefits of being able to lookup certain types without registering all types.
using Cara = import "/capnp/cara.capnp";
struct StructName @<capnp id> $Cara.registerGlobally {}
import cara
cara.GlobalTypeRegistery[<capnp id>].__name__ == 'StructName'
Replacing a struct or interface's implementation.
Sometimes you want to replace how a struct or interface is handled in your
application, but maybe only in your subset of the code. Calling ReplaceTypes
on a struct or interface with an item-map will replace any mention of the keyed
types with the values. To explain more simply, here's an example:
# example.capnp
struct Root {
field @0 :SubType1;
struct SubType1 {
subField @0 :Host;
}
struct Host {
hostname @0 :Text;
port @1 :Int16;
}
}
First, import it as usual.
from example_capnp import Root
Next, let's construct it with a dict, as normal.
foo = Root({'field': {'subField': {'hostname': 'cara.readthedocs.org'}}})
assert foo.field.subField.hostname == 'cara.readthedocs.org'
Now, let's create a new class that takes a dict matching the Host
struct.
class HostReplacement(object):
def __init__(self, dct):
self._hostname = dct.get('hostname', 'www.google.com')
self._port = dct.get('port', 80)
self.socket = socket.create_connection((self._hostname, self._port))
Next, we create a new struct that is just like Root
, except with our new
class in the right place. Note that we have to use a list of tuples, similar to
what a python dict's items()
method returns, because many types aren't
hashable.
NewRoot = Root.ReplaceTypes([(Root.Host, HostReplacement)])
new_foo = NewRoot(foo)
assert isinstance(new_foo.field.subField, HostReplacement)
Now the NewRoot
struct is exactly the same as Root
, except anywhere that
the Host
struct was is now HostReplacement
, even in its nested structs.
Note the names aren't changed, only the underlying type.
assert NewRoot.Host is not Root.Host
assert NewRoot.Host is HostReplacement