__rhandle = $rhandle; $this->__epoch = $epoch; } public function __destruct() { \ShirabeRustObjectRegistry::release($this->__rhandle); } public function __shirabeRustHandleDescriptor(): array { return [ '__rhandle' => $this->__rhandle, '__class' => static::class, '__epoch' => $this->__epoch, ]; } public function __clone() { // PHP has already shallow-copied this stub, so both copies would point at one // entity and release it twice. The Rust side clones the entity instead, applying // whatever __clone semantics the real class defines, and this copy rebinds to the // fresh handle. Entities without clone semantics answer with an explicit error. [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []); \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this); } public function __get($name) { return \ShirabeRpcRuntime::callRust($this->__rhandle, '__get', [$name]); } public function __set($name, $value): void { \ShirabeRpcRuntime::callRust($this->__rhandle, '__set', [$name, $value]); } public function __isset($name): bool { return \ShirabeRpcRuntime::callRust($this->__rhandle, '__isset', [$name]); } public function __unset($name): void { \ShirabeRpcRuntime::callRust($this->__rhandle, '__unset', [$name]); } public function __construct(IOInterface $io, Config $config, array $options = [], bool $disableTls = false) { [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust(0, '__shirabeConstruct', [static::class, [$io, $config, $options, $disableTls]]); \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this); } private const STATUS_QUEUED = 1; private const STATUS_STARTED = 2; private const STATUS_COMPLETED = 3; private const STATUS_FAILED = 4; private const STATUS_ABORTED = 5; public static function outputWarnings(IOInterface $io, string $url, $data): void { $cleanMessage = static function ($msg) use ($io) { if (!$io->isDecorated()) { $msg = Preg::replace('{'.chr(27).'\\[[;\d]*m}u', '', $msg); } return $msg; }; // legacy warning/info keys foreach (['warning', 'info'] as $type) { if (empty($data[$type])) { continue; } if (!empty($data[$type . '-versions'])) { $versionParser = new VersionParser(); $constraint = $versionParser->parseConstraints($data[$type . '-versions']); $composer = new Constraint('==', $versionParser->normalize(Composer::getVersion())); if (!$constraint->matches($composer)) { continue; } } $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$cleanMessage($data[$type]).''); } // modern Composer 2.2+ format with support for multiple warning/info messages foreach (['warnings', 'infos'] as $key) { if (empty($data[$key])) { continue; } $versionParser = new VersionParser(); foreach ($data[$key] as $spec) { $type = substr($key, 0, -1); $constraint = $versionParser->parseConstraints($spec['versions']); $composer = new Constraint('==', $versionParser->normalize(Composer::getVersion())); if (!$constraint->matches($composer)) { continue; } $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$cleanMessage($spec['message']).''); } } } public static function getExceptionHints(\Throwable $e): ?array { if (!$e instanceof TransportException) { return null; } if ( false !== strpos($e->getMessage(), 'Resolving timed out') || false !== strpos($e->getMessage(), 'Could not resolve host') ) { Silencer::suppress(); $testConnectivity = file_get_contents('https://8.8.8.8', false, stream_context_create([ 'ssl' => ['verify_peer' => false], 'http' => ['follow_location' => false, 'ignore_errors' => true], ])); Silencer::restore(); if (false !== $testConnectivity) { return [ 'The following exception probably indicates you have misconfigured DNS resolver(s)', ]; } return [ 'The following exception probably indicates you are offline or have misconfigured DNS resolver(s)', ]; } return null; } public static function isCurlEnabled(): bool { return \extension_loaded('curl') && \function_exists('curl_multi_exec') && \function_exists('curl_multi_init'); } public function get(string $url, array $options = []) { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'get', [$url, $options]); } public function add(string $url, array $options = []) { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'add', [$url, $options]); } public function copy(string $url, string $to, array $options = []) { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'copy', [$url, $to, $options]); } public function addCopy(string $url, string $to, array $options = []) { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'addCopy', [$url, $to, $options]); } public function getOptions() { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'getOptions', []); } public function setOptions(array $options) { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'setOptions', [$options]); } public function wait(?int $index = null) { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'wait', [$index]); } public function enableAsync(): void { \ShirabeRpcRuntime::callRust($this->__rhandle, 'enableAsync', []); } public function countActiveJobs(?int $index = null): int { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'countActiveJobs', [$index]); } }