capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

calculator.capnp (4651B)


      1 # Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
      2 # Licensed under the MIT License:
      3 #
      4 # Permission is hereby granted, free of charge, to any person obtaining a copy
      5 # of this software and associated documentation files (the "Software"), to deal
      6 # in the Software without restriction, including without limitation the rights
      7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 # copies of the Software, and to permit persons to whom the Software is
      9 # furnished to do so, subject to the following conditions:
     10 #
     11 # The above copyright notice and this permission notice shall be included in
     12 # all copies or substantial portions of the Software.
     13 #
     14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 # THE SOFTWARE.
     21 
     22 @0x85150b117366d14b;
     23 
     24 interface Calculator {
     25   # A "simple" mathematical calculator, callable via RPC.
     26   #
     27   # But, to show off Cap'n Proto, we add some twists:
     28   #
     29   # - You can use the result from one call as the input to the next
     30   #   without a network round trip.  To accomplish this, evaluate()
     31   #   returns a `Value` object wrapping the actual numeric value.
     32   #   This object may be used in a subsequent expression.  With
     33   #   promise pipelining, the Value can actually be used before
     34   #   the evaluate() call that creates it returns!
     35   #
     36   # - You can define new functions, and then call them.  This again
     37   #   shows off pipelining, but it also gives the client the
     38   #   opportunity to define a function on the client side and have
     39   #   the server call back to it.
     40   #
     41   # - The basic arithmetic operators are exposed as Functions, and
     42   #   you have to call getOperator() to obtain them from the server.
     43   #   This again demonstrates pipelining -- using getOperator() to
     44   #   get each operator and then using them in evaluate() still
     45   #   only takes one network round trip.
     46 
     47   evaluate @0 (expression :Expression) -> (value :Value);
     48   # Evaluate the given expression and return the result.  The
     49   # result is returned wrapped in a Value interface so that you
     50   # may pass it back to the server in a pipelined request.  To
     51   # actually get the numeric value, you must call read() on the
     52   # Value -- but again, this can be pipelined so that it incurs
     53   # no additional latency.
     54 
     55   struct Expression {
     56     # A numeric expression.
     57 
     58     union {
     59       literal @0 :Float64;
     60       # A literal numeric value.
     61 
     62       previousResult @1 :Value;
     63       # A value that was (or, will be) returned by a previous
     64       # evaluate().
     65 
     66       parameter @2 :UInt32;
     67       # A parameter to the function (only valid in function bodies;
     68       # see defFunction).
     69 
     70       call :group {
     71         # Call a function on a list of parameters.
     72         function @3 :Function;
     73         params @4 :List(Expression);
     74       }
     75     }
     76   }
     77 
     78   interface Value {
     79     # Wraps a numeric value in an RPC object.  This allows the value
     80     # to be used in subsequent evaluate() requests without the client
     81     # waiting for the evaluate() that returns the Value to finish.
     82 
     83     read @0 () -> (value :Float64);
     84     # Read back the raw numeric value.
     85   }
     86 
     87   defFunction @1 (paramCount :Int32, body :Expression)
     88               -> (func :Function);
     89   # Define a function that takes `paramCount` parameters and returns the
     90   # evaluation of `body` after substituting these parameters.
     91 
     92   interface Function {
     93     # An algebraic function.  Can be called directly, or can be used inside
     94     # an Expression.
     95     #
     96     # A client can create a Function that runs on the server side using
     97     # `defFunction()` or `getOperator()`.  Alternatively, a client can
     98     # implement a Function on the client side and the server will call back
     99     # to it.  However, a function defined on the client side will require a
    100     # network round trip whenever the server needs to call it, whereas
    101     # functions defined on the server and then passed back to it are called
    102     # locally.
    103 
    104     call @0 (params :List(Float64)) -> (value :Float64);
    105     # Call the function on the given parameters.
    106   }
    107 
    108   getOperator @2 (op :Operator) -> (func :Function);
    109   # Get a Function representing an arithmetic operator, which can then be
    110   # used in Expressions.
    111 
    112   enum Operator {
    113     add @0;
    114     subtract @1;
    115     multiply @2;
    116     divide @3;
    117   }
    118 }