turbopack_dev_server/source/
issue_context.rs

1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::{ResolvedVc, Vc};
4use turbo_tasks_fs::FileSystemPath;
5use turbopack_core::introspect::{Introspectable, IntrospectableChildren};
6
7use super::{
8    ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary, ContentSources,
9    GetContentSourceContent,
10    route_tree::{MapGetContentSourceContent, RouteTree},
11};
12
13#[turbo_tasks::value]
14pub struct IssueFilePathContentSource {
15    file_path: Option<FileSystemPath>,
16    description: RcStr,
17    source: ResolvedVc<Box<dyn ContentSource>>,
18}
19
20#[turbo_tasks::value_impl]
21impl IssueFilePathContentSource {
22    #[turbo_tasks::function]
23    pub fn new_file_path(
24        file_path: FileSystemPath,
25        description: RcStr,
26        source: ResolvedVc<Box<dyn ContentSource>>,
27    ) -> Vc<Self> {
28        IssueFilePathContentSource {
29            file_path: Some(file_path),
30            description,
31            source,
32        }
33        .cell()
34    }
35
36    #[turbo_tasks::function]
37    pub fn new_description(
38        description: RcStr,
39        source: ResolvedVc<Box<dyn ContentSource>>,
40    ) -> Vc<Self> {
41        IssueFilePathContentSource {
42            file_path: None,
43            description,
44            source,
45        }
46        .cell()
47    }
48}
49
50#[turbo_tasks::value_impl]
51impl ContentSource for IssueFilePathContentSource {
52    #[turbo_tasks::function]
53    async fn get_routes(self: ResolvedVc<Self>) -> Result<Vc<RouteTree>> {
54        let this = self.await?;
55        let routes = this.source.get_routes();
56        Ok(routes.map_routes(Vc::upcast(
57            IssueContextContentSourceMapper { source: self }.cell(),
58        )))
59    }
60
61    #[turbo_tasks::function]
62    fn get_children(&self) -> Vc<ContentSources> {
63        Vc::cell(vec![self.source])
64    }
65}
66
67#[turbo_tasks::value]
68struct IssueContextContentSourceMapper {
69    source: ResolvedVc<IssueFilePathContentSource>,
70}
71
72#[turbo_tasks::value_impl]
73impl MapGetContentSourceContent for IssueContextContentSourceMapper {
74    #[turbo_tasks::function]
75    fn map_get_content(
76        &self,
77        get_content: ResolvedVc<Box<dyn GetContentSourceContent>>,
78    ) -> Vc<Box<dyn GetContentSourceContent>> {
79        Vc::upcast(
80            IssueContextGetContentSourceContent {
81                get_content,
82                source: self.source,
83            }
84            .cell(),
85        )
86    }
87}
88
89#[turbo_tasks::value]
90struct IssueContextGetContentSourceContent {
91    get_content: ResolvedVc<Box<dyn GetContentSourceContent>>,
92    source: ResolvedVc<IssueFilePathContentSource>,
93}
94
95#[turbo_tasks::value_impl]
96impl GetContentSourceContent for IssueContextGetContentSourceContent {
97    #[turbo_tasks::function]
98    async fn vary(&self) -> Result<Vc<ContentSourceDataVary>> {
99        Ok(self.get_content.vary())
100    }
101
102    #[turbo_tasks::function]
103    async fn get(&self, path: RcStr, data: ContentSourceData) -> Result<Vc<ContentSourceContent>> {
104        Ok(self.get_content.get(path, data))
105    }
106}
107
108#[turbo_tasks::value_impl]
109impl Introspectable for IssueFilePathContentSource {
110    #[turbo_tasks::function]
111    fn ty(&self) -> Result<Vc<RcStr>> {
112        Ok(
113            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
114                source.ty()
115            } else {
116                Vc::cell(rcstr!("IssueContextContentSource"))
117            },
118        )
119    }
120
121    #[turbo_tasks::function]
122    async fn title(&self) -> Result<Vc<RcStr>> {
123        Ok(
124            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
125                let title = source.title().await?;
126                Vc::cell(format!("{}: {}", self.description, title).into())
127            } else {
128                Vc::cell(self.description.clone())
129            },
130        )
131    }
132
133    #[turbo_tasks::function]
134    fn details(&self) -> Result<Vc<RcStr>> {
135        Ok(
136            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
137                source.details()
138            } else {
139                Vc::cell(RcStr::default())
140            },
141        )
142    }
143
144    #[turbo_tasks::function]
145    fn children(&self) -> Result<Vc<IntrospectableChildren>> {
146        Ok(
147            if let Some(source) = ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.source) {
148                source.children()
149            } else {
150                Vc::cell(Default::default())
151            },
152        )
153    }
154}