Maintain local ⭤ remote in sync with automatic AT Protocol parity for Laravel (alpha & unstable)
1<?php
2
3namespace SocialDept\AtpParity\Support;
4
5use Closure;
6use Illuminate\Database\Eloquent\Model;
7use SocialDept\AtpParity\RecordMapper;
8use SocialDept\AtpSchema\Data\Data;
9
10/**
11 * Adapter for using atp-schema generated DTOs as record types.
12 *
13 * This allows you to use the auto-generated schema classes directly
14 * without creating custom Record classes.
15 *
16 * Example:
17 *
18 * use SocialDept\AtpSchema\Generated\App\Bsky\Feed\Post;
19 * use App\Models\Post as PostModel;
20 *
21 * $mapper = new SchemaMapper(
22 * schemaClass: Post::class,
23 * modelClass: PostModel::class,
24 * toAttributes: fn(Post $p) => [
25 * 'content' => $p->text,
26 * 'published_at' => $p->createdAt,
27 * ],
28 * toRecordData: fn(PostModel $m) => [
29 * 'text' => $m->content,
30 * 'createdAt' => $m->published_at->toIso8601String(),
31 * ],
32 * );
33 *
34 * $registry->register($mapper);
35 *
36 * @template TSchema of Data
37 * @template TModel of Model
38 *
39 * @extends RecordMapper<TSchema, TModel>
40 */
41class SchemaMapper extends RecordMapper
42{
43 /**
44 * @param class-string<TSchema> $schemaClass The atp-schema generated class
45 * @param class-string<TModel> $modelClass The Eloquent model class
46 * @param Closure(TSchema): array $toAttributes Convert schema to model attributes
47 * @param Closure(TModel): array $toRecordData Convert model to record data
48 */
49 public function __construct(
50 protected string $schemaClass,
51 protected string $modelClass,
52 protected Closure $toAttributes,
53 protected Closure $toRecordData,
54 ) {}
55
56 public function recordClass(): string
57 {
58 return $this->schemaClass;
59 }
60
61 public function modelClass(): string
62 {
63 return $this->modelClass;
64 }
65
66 protected function recordToAttributes(Data $record): array
67 {
68 return ($this->toAttributes)($record);
69 }
70
71 protected function modelToRecordData(Model $model): array
72 {
73 return ($this->toRecordData)($model);
74 }
75}