Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: pkg/json_rpc_2/lib/src/parameters.dart

Issue 205533005: Create a package that implements a JSON-RPC 2.0 server. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library json_rpc_2.parameters;
6
7 import 'dart:math' as math;
8
9 import 'exception.dart';
10
11 /// A wrapper for the parameters to a server method.
12 ///
13 /// JSON-RPC 2.0 allows parameters that are either a list or a map. This class
14 /// provides functions that not only assert that the parameters object is the
15 /// correct type, but also that the expected arguments exist and are themselves
16 /// the correct type.
17 class Parameters {
18 /// The name of the method that this request called.
19 final String method;
20
21 /// The underlying value of the parameters.
Bob Nystrom 2014/03/20 18:25:58 "parameters" -> "parameters object"
nweiz 2014/03/20 22:55:41 Done.
22 final value;
23
24 /// The path to this parameters map, or null if this is the top-level
25 /// parameters map.
Bob Nystrom 2014/03/20 18:25:58 How about a bit explaining how this is formatted?
nweiz 2014/03/20 22:55:41 Done.
26 final String _prefix;
27
28 /// Returns the length of the positional parameters array.
29 ///
30 /// If the request passed named parameters rather than positional parameters,
31 /// this will reject the request.
32 int get length {
33 _assertPositional();
34 return value.length;
35 }
36
37 Parameters(this.method, this.value, [this._prefix]);
38
39 /// Returns the parameter named [name].
40 ///
41 /// If there is no parameter named [name] and [orElse] was passed, this will
42 /// call [orElse] and return its result. If [orElse] was not passed, this will
43 /// reject the request.
44 ///
45 /// If the request passed positional parameters rather than named parameters,
46 /// this will reject the request.
47 getNamed(String name, {orElse()}) {
48 _assertNamed();
49 if (value.containsKey(name)) return value[name];
50 if (orElse != null) return orElse();
51 throw new RpcException.invalidParams('Request for method "$method" is '
52 'missing required parameter "${_prefixName(name)}".');
53 }
54
55 /// Returns the numeric parameter named [name].
56 ///
57 /// If there is no parameter named [name] and [orElse] was passed, this will
58 /// call [orElse] and return its result. If [orElse] was not passed, this will
59 /// reject the request.
60 ///
61 /// If the parameter named [name] is not a number or if the request passed
62 /// positional parameters rather than named parameters, this will reject the
63 /// request.
64 num getNum(String name, {num orElse()}) =>
65 _getTyped(name, 'a number', (value) => value is num, orElse);
66
67 /// Returns the integer parameter named [name].
68 ///
69 /// If there is no parameter named [name] and [orElse] was passed, this will
70 /// call [orElse] and return its result. If [orElse] was not passed, this will
71 /// reject the request.
72 ///
73 /// If the parameter named [name] is not an integer or if the request passed
74 /// positional parameters rather than named parameters, this will reject the
75 /// request.
76 int getInt(String name, {int orElse()}) =>
77 _getTyped(name, 'an integer', (value) => value is int, orElse);
Bob Nystrom 2014/03/20 18:25:58 This will do weird things in dart2js. If the value
nweiz 2014/03/20 22:55:41 I thought about only having [getNum], but I think
78
79 /// Returns the boolean parameter named [name].
80 ///
81 /// If there is no parameter named [name] and [orElse] was passed, this will
82 /// call [orElse] and return its result. If [orElse] was not passed, this will
83 /// reject the request.
84 ///
85 /// If the parameter named [name] is not a boolean or if the request passed
86 /// positional parameters rather than named parameters, this will reject the
87 /// request.
88 bool getBool(String name, {bool orElse()}) =>
89 _getTyped(name, 'a boolean', (value) => value is bool, orElse);
90
91 /// Returns the string parameter named [name].
92 ///
93 /// If there is no parameter named [name] and [orElse] was passed, this will
94 /// call [orElse] and return its result. If [orElse] was not passed, this will
95 /// reject the request.
96 ///
97 /// If the parameter named [name] is not a string or if the request passed
98 /// positional parameters rather than named parameters, this will reject the
99 /// request.
100 String getString(String name, {String orElse()}) =>
101 _getTyped(name, 'a string', (value) => value is String, orElse);
102
103 /// Returns the list parameter named [name].
104 ///
105 /// If there is no parameter named [name] and [orElse] was passed, this will
106 /// call [orElse] and return its result. If [orElse] was not passed, this will
107 /// reject the request.
108 ///
109 /// It's safe to modify the returned list.
Bob Nystrom 2014/03/20 18:25:58 If we claim to support this, we're stuck with the
nweiz 2014/03/20 22:55:41 Thinking this over more I think it's probably bett
Bob Nystrom 2014/03/21 00:36:02 SGTM.
110 ///
111 /// If the parameter named [name] is not a list or if the request passed
112 /// positional parameters rather than named parameters, this will reject the
113 /// request.
114 List getList(String name, {List orElse()}) =>
115 _getTyped(name, 'an Array', (value) => value is List, orElse).toList();
116
117 /// Returns the map parameter named [name].
118 ///
119 /// If there is no parameter named [name] and [orElse] was passed, this will
120 /// call [orElse] and return its result. If [orElse] was not passed, this will
121 /// reject the request.
122 ///
123 /// It's safe to modify the returned map.
Bob Nystrom 2014/03/20 18:25:58 Ditto.
nweiz 2014/03/20 22:55:41 See above.
124 ///
125 /// If the parameter named [name] is not a map or if the request passed
126 /// positional parameters rather than named parameters, this will reject the
127 /// request.
128 Map getMap(String name, {Map orElse()}) {
129 var result = _getTyped(name, 'an Object', (value) => value is Map, orElse);
130 return new Map.from(result);
131 }
132
133 /// Returns a view of the map parameter named [name] as a [Parameters] object.
134 ///
135 /// This can be useful if the request parameters contains nested objects whose
136 /// structure needs to be validated.
137 ///
138 /// If there is no parameter named [name], if the parameter named [name] is
139 /// not a map, or if the request passed positional parameters rather than
Bob Nystrom 2014/03/20 18:25:58 Why can't the nested parameter be a list?
nweiz 2014/03/20 22:55:41 N/A
140 /// named parameters, this will reject the request.
141 Parameters getNested(String name) {
142 var map = getMap(name, orElse: () => {});
143 var nested = new Parameters(method, map, _prefixName(name));
144 return nested;
145 }
146
147 /// Returns [index]th positional parameter array.
Bob Nystrom 2014/03/20 18:25:58 This is confusingly written. How about: "Returns t
nweiz 2014/03/20 22:55:41 N/A
148 ///
149 /// If the request passed named parameters rather than positional parameters,
150 /// or if there aren't enough positional parameters to return the [index]th,
Bob Nystrom 2014/03/20 18:25:58 "indexth" -> "indexth one".
nweiz 2014/03/20 22:55:41 N/A
151 /// this will reject the request.
152 getPositional(int index) {
153 _assertPositional();
154 if (index < value.length) return value[index];
155 throw new RpcException.invalidParams('Method "$method" requires at least '
156 '${index + 1} arguments.');
157 }
158
159 /// Get a parameter named [named] that matches [test], or the value of calling
160 /// [orElse].
161 ///
162 /// [type] is used for the error message. It should begin with an indefinite
163 /// article.
164 _getTyped(String name, String type, bool test(value), orElse()) {
165 var result = getNamed(name, orElse: orElse);
166 if (!value.containsKey(name)) return result;
167 if (test(value[name])) return value[name];
168
169 throw new RpcException.invalidParams('Parameter "${_prefixName(name)}" '
170 'for method "$method" must be $type, but was "${value[name]}".');
171 }
172
173 /// Asserts that [value] is a positional argument list.
174 void _assertPositional() {
175 if (value is List) return;
176 throw new RpcException.invalidParams('Parameters for method "$method" '
177 'must be passed by position.');
Bob Nystrom 2014/03/20 18:25:58 Handle nesting in the error message, here and belo
nweiz 2014/03/20 22:55:41 Done.
178 }
179
180 /// Asserts that [value] is a named argument map.
181 void _assertNamed() {
182 if (value is Map) return;
183 throw new RpcException.invalidParams('Parameters for method "$method" '
184 'must be passed by name.');
185 }
186
187 /// Returns [name] with [_prefix] attached.
188 String _prefixName(String name) => _prefix == null ? name : "$_prefix.$name";
189 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698