<?php
 declare(strict_types=1); namespace SpomkyLabs\Pki\X501\ASN1; use SpomkyLabs\Pki\ASN1\Type\Constructed\Sequence; use SpomkyLabs\Pki\X501\ASN1\AttributeValue\AttributeValue; use Stringable; final class AttributeTypeAndValue implements Stringable { private function __construct( private readonly AttributeType $type, private readonly AttributeValue $value ) { } public function __toString(): string { return $this->toString(); } public static function create(AttributeType $type, AttributeValue $value): self { return new self($type, $value); } public static function fromASN1(Sequence $seq): self { $type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier()); $value = AttributeValue::fromASN1ByOID($type->oid(), $seq->at(1)); return self::create($type, $value); } public static function fromAttributeValue(AttributeValue $value): self { return self::create(AttributeType::create($value->oid()), $value); } public function value(): AttributeValue { return $this->value; } public function toASN1(): Sequence { return Sequence::create($this->type->toASN1(), $this->value->toASN1()); } public function toString(): string { return $this->type->typeName() . '=' . $this->value->rfc2253String(); } public function equals(self $other): bool { if ($this->oid() !== $other->oid()) { return false; } $matcher = $this->value->equalityMatchingRule(); return $matcher->compare($this->value->stringValue(), $other->value->stringValue()) === true; } public function type(): AttributeType { return $this->type; } public function oid(): string { return $this->type->oid(); } } 