use Countable;
use Generator;
-use http\{
- Client, Client\Request, Message\Body, QueryString, Url
-};
+use http\{Client, Client\Request, Message\Body, QueryString, Url};
+use Iterator;
use IteratorAggregate;
-use Psr\Log\{
- LoggerInterface, NullLogger
-};
-use seekat\API\{
- Call, Consumer, ContentType, Future, Iterator, Links
-};
+use Psr\Log\{LoggerInterface, NullLogger};
+use seekat\API\{Call, Consumer, ContentType, Future, Links};
use seekat\Exception\InvalidArgumentException;
class API implements IteratorAggregate, Countable {
+ /**
+ * API version
+ * @var int
+ */
+ private $version = 3;
+
/**
* The current API endpoint URL
* @var Url
/**
* Create a new API endpoint root
*
+ * @codeCoverageIgnore
+ *
* @param Future $future pretending to fulfill promises
* @param array $headers Standard request headers, defaults to ["Accept" => "application/vnd.github.v3+json"]
* @param Url $url The API's endpoint, defaults to https://api.github.com
$this->logger = $log ?? new NullLogger;
$this->url = $url ?? new Url("https://api.github.com");
$this->client = $client ?? new Client;
+ $this->type = new ContentType($this->version, "json");
$this->headers = (array) $headers + [
- "Accept" => "application/vnd.github.v3+json"
+ "Accept" => $this->type->getContentType()
];
}
(string) $this->url,
(string) $that->url
],
+ "data" => $that->data
]);
return $that;
$this->logger->debug(__FUNCTION__);
$consumer = new Consumer($this->getFuture(), function() {
- $this->client->send();
+ $this->client->send();
});
invoke:
* @return string
*/
function __toString() : string {
- if (is_scalar($this->data)) {
- return (string) $this->data;
- }
-
- /* FIXME */
- return json_encode($this->data);
+ return (string) $this->type->encode($this->data);
}
/**
* @return Iterator
*/
function getIterator() : Iterator {
- return new Iterator($this);
+ foreach ($this->data as $key => $cur) {
+ if ($this->__get($key)->exists("url", $url)) {
+ $url = new Url($url);
+ $val = $this->withUrl($url)->withData($cur);
+ } else {
+ $val = $this->__get($key)->withData($cur);
+ }
+ yield $key => $val;
+ }
}
/**
* @return int
*/
function count() : int {
- return count($this->data);
+ if (is_array($this->data)) {
+ $count = count($this->data);
+ } else if ($this->data instanceof Countable) {
+ $count = count($this->data);
+ } else if (is_object($this->data)) {
+ $count = count((array) $this->data);
+ } else {
+ $count = 0;
+ }
+ $this->logger->debug("count()", [
+ "of type" => typeof($this->data),
+ "count" => $count
+ ]);
+ return $count;
}
/**
return $this->links;
}
+ /**
+ * @return int
+ */
+ function getVersion() : int {
+ return $this->version;
+ }
+
/**
* Export the endpoint's underlying data
*
* @return API clone
*/
function as(string $type, bool $keepdata = true) : API {
- $that = ContentType::apply($this, $type);
+ $ct = new ContentType($this->version, $type);
+
+ $that = $ct->apply($this);
+ $that->type = $ct;
+
if (!$keepdata) {
$that->data = null;
}
$seg, typeof($this->data, false), $exists ? "true" : "false"
), [
"url" => (string) $this->url,
- "val" => $val,
+ "val" => typeof($val, false),
]);
return $exists;
$url = $this->url->mod(["query" => new QueryString($args)]);
$request = new Request($method, $url, ((array) $headers) + $this->headers,
- $body = is_array($body) ? json_encode($body) : (
- is_resource($body) ? new Body($body) : (
- is_scalar($body) ? (new Body)->append($body) :
- $body)));
+ $body = $this->type->encode(is_resource($body) ? new Body($body) : $body));
$this->logger->info("request -> deferred", [
"method" => $method,